返回

基于Promise /A+规范手写Promise

前端

什么是 Promise

Promise 是 JavaScript 中用来处理异步编程的一种对象。它可以让你在执行异步操作时,不用再使用回调函数来处理结果。你可以使用 Promise 来将异步操作的结果传递给其他函数,以便在异步操作完成后执行相应的操作。

Promise 的常见用法

Promise 的常见用法包括:

  • 处理异步操作的结果
  • 将多个异步操作串行化或并行化执行
  • 错误处理
  • 状态转换

Promise 的实现

Promise 的实现主要涉及以下几个方面:

  • 状态管理
  • 值传递
  • 错误处理
  • then 方法
  • catch 方法

状态管理

Promise 的状态有三种:pending、fulfilled 和 rejected。pending 表示异步操作正在进行中,fulfilled 表示异步操作成功完成,rejected 表示异步操作失败。

值传递

当 Promise 的状态变为 fulfilled 时,可以使用 then 方法来获取异步操作的结果。当 Promise 的状态变为 rejected 时,可以使用 catch 方法来捕获错误。

错误处理

Promise 的错误处理与普通 JavaScript 的错误处理类似。可以使用 try...catch 语句来捕获错误,也可以使用 Promise 的 catch 方法来捕获错误。

then 方法

then 方法是 Promise 的一个重要方法,它允许你在异步操作完成后执行相应的操作。then 方法有两个参数,第一个参数是成功回调函数,第二个参数是失败回调函数。

catch 方法

catch 方法是 Promise 的另一个重要方法,它允许你在异步操作失败时执行相应的操作。catch 方法只有一个参数,是失败回调函数。

手写 Promise

现在,我们来看看如何手写一个 Promise。首先,我们需要定义一个 Promise 构造函数。Promise 构造函数接受一个参数,该参数是一个执行器函数。执行器函数有两个参数,分别是 resolve 和 reject。resolve 用于将 Promise 的状态变为 fulfilled,reject 用于将 Promise 的状态变为 rejected。

function Promise(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(value);
      });
    }
  };

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

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

接下来,我们需要定义 then 方法和 catch 方法。then 方法接受两个参数,分别是成功回调函数和失败回调函数。catch 方法接受一个参数,是失败回调函数。

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

Promise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected);
};

最后,我们需要定义一个静态方法 resolve 和 reject。resolve 方法用于创建一个 Promise 对象,并将其状态设置为 fulfilled。reject 方法用于创建一个 Promise 对象,并将其状态设置为 rejected。

Promise.resolve = function (value) {
  return new Promise((resolve, reject) => {
    resolve(value);
  });
};

Promise.reject = function (reason) {
  return new Promise((resolve, reject) => {
    reject(reason);
  });
};

以上就是如何手写一个 Promise 的基本步骤。在实际开发中,我们可以使用一些现成的 Promise 库,例如 Bluebird、Q 和 RSVP.js 等。这些库提供了更丰富的 API 和更好的性能,可以帮助我们更轻松地处理异步编程。