返回

PromiseA+规范 - 手写Promise的艺术

前端

PromiseA+规范的深入理解

PromiseA+规范是JavaScript中异步编程的标准规范,它定义了Promise对象的行为和用法。Promise对象可以用来表示一个异步操作的结果,它提供了一个统一的接口来处理异步任务。

Promise对象有三个状态:pending(等待)、fulfilled(完成)和rejected(拒绝)。当一个Promise对象被创建时,它处于pending状态。当异步操作完成时,Promise对象的状态变为fulfilled或rejected,这取决于异步操作是否成功。

Promise的本质 - then方法

Promise对象最重要的特性就是它的then方法。then方法允许我们注册回调函数,以便在Promise对象的状态改变时执行相应的操作。then方法接受两个参数:

  • onFulfilled:当Promise对象的状态变为fulfilled时执行的回调函数。
  • onRejected:当Promise对象的状态变为rejected时执行的回调函数。

手写Promise的then方法

为了更好地理解Promise的本质,我们现在来一步步手写Promise的then方法。首先,我们需要定义一个Promise类:

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

    // 立即执行executor函数
    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    // 处理onFulfilled参数
    if (typeof onFulfilled !== 'function') {
      onFulfilled = function(value) {
        return value;
      };
    }

    // 处理onRejected参数
    if (typeof onRejected !== 'function') {
      onRejected = function(reason) {
        throw reason;
      };
    }

    // 创建一个新的Promise对象
    const newPromise = new Promise((resolve, reject) => {
      // 如果当前Promise对象的状态是pending,则将回调函数存储起来
      if (this.state === 'pending') {
        this.onFulfilledCallbacks.push(() => {
          // 使用try-catch块来捕获onFulfilled函数可能抛出的错误
          try {
            // 执行onFulfilled函数
            const value = onFulfilled(this.value);
            // 根据onFulfilled函数的返回值来解析新Promise对象的状态
            resolvePromise(newPromise, value);
          } catch (err) {
            // 如果onFulfilled函数抛出错误,则将新Promise对象的状态置为rejected
            reject(err);
          }
        });

        this.onRejectedCallbacks.push(() => {
          // 使用try-catch块来捕获onRejected函数可能抛出的错误
          try {
            // 执行onRejected函数
            const reason = onRejected(this.reason);
            // 根据onRejected函数的返回值来解析新Promise对象的状态
            resolvePromise(newPromise, reason);
          } catch (err) {
            // 如果onRejected函数抛出错误,则将新Promise对象的状态置为rejected
            reject(err);
          }
        });
      }

      // 如果当前Promise对象的状态不是pending,则立即执行回调函数
      else if (this.state === 'fulfilled') {
        // 使用try-catch块来捕获onFulfilled函数可能抛出的错误
        try {
          // 执行onFulfilled函数
          const value = onFulfilled(this.value);
          // 根据onFulfilled函数的返回值来解析新Promise对象的状态
          resolvePromise(newPromise, value);
        } catch (err) {
          // 如果onFulfilled函数抛出错误,则将新Promise对象的状态置为rejected
          reject(err);
        }
      }

      else if (this.state === 'rejected') {
        // 使用try-catch块来捕获onRejected函数可能抛出的错误
        try {
          // 执行onRejected函数
          const reason = onRejected(this.reason);
          // 根据onRejected函数的返回值来解析新Promise对象的状态
          resolvePromise(newPromise, reason);
        } catch (err) {
          // 如果onRejected函数抛出错误,则将新Promise对象的状态置为rejected
          reject(err);
        }
      }
    });

    // 返回新创建的Promise对象
    return newPromise;
  }

  resolve(value) {
    // 检查Promise对象的状态是否为pending
    if (this.state !== 'pending') {
      return;
    }

    // 将Promise对象的状态置为fulfilled
    this.state = 'fulfilled';

    // 将Promise对象的值置为value
    this.value = value;

    // 执行onFulfilledCallbacks中存储的回调函数
    this.onFulfilledCallbacks.forEach((callback) => {
      callback();
    });
  }

  reject(reason) {
    // 检查Promise对象的状态是否为pending
    if (this.state !== 'pending') {
      return;
    }

    // 将Promise对象的状态置为rejected
    this.state = 'rejected';

    // 将Promise对象的原因置为reason
    this.reason = reason;

    // 执行onRejectedCallbacks中存储的回调函数
    this.onRejectedCallbacks.forEach((callback) => {
      callback();
    });
  }
}

// 解析Promise对象的状态
function resolvePromise(promise, x) {
  // 如果promise和x是同一个对象,则抛出TypeError错误
  if (promise === x) {
    throw new TypeError('Cannot resolve a promise with itself');
  }

  // 如果x是一个Promise对象,则将x的状态传递给promise
  if (x instanceof Promise) {
    x.then(
      (value) => {
        resolvePromise(promise, value);
      },
      (reason) => {
        promise.reject(reason);
      }
    );
  }

  // 如果x是一个thenable对象,则将x的状态传递给promise
  else if (typeof x === 'object' || typeof x === 'function') {
    // 尝试获取x的then方法
    let then;
    try {
      then = x.then;
    } catch (err) {
      promise.reject(err);
      return;
    }

    // 如果then是一个函数,则将x的状态传递给promise
    if (typeof then === 'function') {
      let called = false;
      try {
        // 使用try-catch块来捕获then函数可能抛出的错误
        then.call(
          x,
          (y) => {
            // 如果then函数被调用了两次以上,则抛出TypeError错误
            if (called) {
              return;
            }
            called = true;

            resolvePromise(promise, y);
          },
          (r) => {
            // 如果then函数被调用了两次以上,则抛出TypeError错误
            if (called) {
              return;
            }
            called = true;

            promise.reject(r);
          }
        );
      } catch (err) {
        // 如果then函数抛出错误,则将promise的状态置为rejected
        if (!called) {
          promise.reject(err);
        }
      }
    } else {
      promise.resolve(x);
    }
  }

  // 如果x是一个普通值,则将promise的状态置为fulfilled,并将x作为promise的值
  else {
    promise.resolve(x);