侧边栏壁纸
博主头像
Fonda's Lab 博主等级

关山难越,谁悲失路之人?萍水相逢,尽是他乡之客。

  • 累计撰写 49 篇文章
  • 累计创建 27 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

手写Promise(入门思路篇)

LouisFonda
2024-02-11 / 0 评论 / 0 点赞 / 18 阅读 / 0 字 / 正在检测是否收录...

手写 Promise

引言

在 JavaScript 的发展历程中,异步编程一直是一个重要且复杂的领域。随着前端和后端的需求不断增长,JavaScript 社区也不断寻求更好的方式来处理异步操作。最初的解决方案是回调函数,但随着代码复杂度的增加,回调函数逐渐暴露出其弊端。为了解决这些问题,Promise 作为一种新的异步编程解决方案应运而生。

Promise 的历史

JavaScript 最初通过回调函数来处理异步操作。例如,使用 setTimeout、XMLHttpRequest 等进行异步操作时,通常会传递一个回调函数来处理结果。这种方法在简单的异步任务中效果显著,但随着异步流程的复杂化,回调函数的嵌套和处理变得越来越困难,导致了所谓的“回调地狱”(Callback Hell)问题。

为了应对这些挑战,社区提出了 Promise 模式,并在 ES6(ECMAScript 2015)中正式引入了 Promise 对象。Promise 提供了一种更清晰、更直观的方式来处理异步操作,使代码更加简洁、易读、易维护。

Promise 的优势

Promise 主要解决了以下几个问题:

  1. 回调地狱:通过链式调用 .then(),Promise 可以避免回调函数的嵌套,从而使代码更加扁平和易读。
  2. 错误处理:Promise 提供了统一的错误处理机制,通过 .catch() 方法,可以集中处理异步操作中的错误。
  3. 状态管理:Promise 引入了三种状态(Pending、Fulfilled、Rejected),使得异步操作的状态更加明确和可控。
  4. 组合异步操作:通过 Promise.all、Promise.race 等方法,Promise 提供了对多个异步操作的组合处理能力。

实现 Promise 的思路

在实现一个基本的 Promise 时,我们需要了解其核心概念和机制。以下是一个简单的 Promise 实现示例,帮助我们理解其工作原理。

基本结构

首先,我们需要定义一个 Promise 类,并在其中初始化一些状态和数据。

class MyPromise {
  constructor(executor) {
    this.state = 'pending'; // 初始状态
    this.value = undefined; // 成功的值
    this.reason = undefined; // 失败的原因
    this.onFulfilledCallbacks = []; // 成功回调队列
    this.onRejectedCallbacks = []; // 失败回调队列

    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(callback => callback());
      }
    };

    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(callback => callback());
      }
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
}

then 方法

接下来,我们实现 then 方法,用于注册成功和失败的回调函数。

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  if (this.state === 'fulfilled') {
    onFulfilled(this.value);
  } else if (this.state === 'rejected') {
    onRejected(this.reason);
  } else {
    this.onFulfilledCallbacks.push(() => {
      onFulfilled(this.value);
    });
    this.onRejectedCallbacks.push(() => {
      onRejected(this.reason);
    });
  }
};

支持链式调用

为了支持链式调用,我们需要在 then 方法中返回一个新的 Promise,并且在其中处理回调函数的返回值。

  then(onFulfilled, onRejected) {
    const self = this;
    return new MyPromise((resolve, reject) => {
      if (self.state === 'fulfilled') {
        try {
          const x = onFulfilled(self.value);
          resolve(x);
        } catch (error) {
          reject(error);
        }
      } else if (self.state === 'rejected') {
        try {
          const x = onRejected(self.reason);
          resolve(x);
        } catch (error) {
          reject(error);
        }
      } else {
        self.onFulfilledCallbacks.push(() => {
          try {
            const x = onFulfilled(self.value);
            resolve(x);
          } catch (error) {
            reject(error);
          }
        });
        self.onRejectedCallbacks.push(() => {
          try {
            const x = onRejected(self.reason);
            resolve(x);
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }

完整示例

以下是一个完整的 MyPromise 实现示例,包含基本的 resolve、reject、then 方法和状态管理。

class MyPromise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(callback => callback());
      }
    };

    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(callback => callback());
      }
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    const self = this;
    return new MyPromise((resolve, reject) => {
      if (self.state === 'fulfilled') {
        try {
          const x = onFulfilled(self.value);
          resolve(x);
        } catch (error) {
          reject(error);
        }
      } else if (self.state === 'rejected') {
        try {
          const x = onRejected(self.reason);
          resolve(x);
        } catch (error) {
          reject(error);
        }
      } else {
        self.onFulfilledCallbacks.push(() => {
          try {
            const x = onFulfilled(self.value);
            resolve(x);
          } catch (error) {
            reject(error);
          }
        });
        self.onRejectedCallbacks.push(() => {
          try {
            const x = onRejected(self.reason);
            resolve(x);
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }
}

总结

通过这篇文章,我们回顾了 Promise 的历史,了解了为什么要引入 Promise 以及它解决了哪些问题。我们还详细讲解了如何手写一个基本的 Promise 实现,包括其核心概念和工作原理。通过这个示例,我们可以更好地理解异步编程的关键问题,并掌握更高级的 JavaScript 技巧。

0

评论区