怎样实现一个符合Promise A+规范的Promise库?

实现符合Promise A+规范的Promise库需正确处理状态机、异步解析与then链式调用,核心包括:1. 定义pending、fulfilled、rejected三种不可逆状态;2. 构造函数中通过resolve/reject控制状态变更并维护回调队列;3. then方法返回新Promise,确保异步执行与错误捕获;4. 实现resolvePromise函数处理返回值x,递归解析thenable对象并防止循环引用。严格遵循规范可确保兼容性,建议使用promises-aplus-tests验证。

怎样实现一个符合Promise A+规范的Promise库?

实现一个符合 Promise A+ 规范的 Promise 库,核心在于正确处理状态机、异步解析和 then 方法的链式调用。重点是遵循规范中对 thenable 处理、状态不可逆变更、异步执行以及错误捕获的要求。

1. 理解 Promise 的三种状态

Promise 有三个状态:

  • pending:初始状态,可变为 fulfilled 或 rejected
  • fulfilled:成功状态,不可再改变
  • rejected:失败状态,不可再改变

状态一旦从 pending 变为 fulfilled 或 rejected,就不能再更改。构造函数中通过变量记录当前状态,并在 resolve 和 reject 函数中进行状态变更控制。

2. 实现基本结构与状态管理

定义构造函数,接收一个执行器函数(executor),内部维护状态、值和回调队列:

怎样实现一个符合Promise A+规范的Promise库?

库宝AI

库宝ai是一款功能多样的智能伙伴助手,涵盖AI写作辅助、智能设计、图像生成、智能对话等多个方面。

怎样实现一个符合Promise A+规范的Promise库?109

查看详情 怎样实现一个符合Promise A+规范的Promise库?

function MyPromise(executor) {
  this.status = ‘pending’;
  this.value = undefined;
  this.reason = undefined;
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

  const resolve = (value) => {
    if (this.status === ‘pending’) {
      this.status = ‘fulfilled’;
      this.value = value;
      this.onFulfilledCallbacks.forEach(fn => fn());
    }
  };

  const reject = (reason) => {
    if (this.status === ‘pending’) {
      this.status = ‘rejected’;
      this.reason = reason;
      this.onRejectedCallbacks.forEach(fn => fn());
    }
  };

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

3. 实现 then 方法

then 方法必须返回一个新的 Promise,支持链式调用。这是 Promise A+ 的核心要求之一。要处理 onFulfilled 和 onRejected 的可选性、异步执行、值穿透和错误传播。

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  onFulfilled = typeof onFulfilled === ‘function’ ? onFulfilled : val => val;
  onRejected = typeof onRejected === ‘function’ ? onRejected : err => { throw err; };

  const promise2 = new MyPromise((resolve, reject) => {
    if (this.status === ‘fulfilled’) {
      setTimeout(() => {
        try {
          const x = onFulfilled(this.value);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      }, 0);
    }

    if (this.status === ‘rejected’) {
      setTimeout(() => {
        try {
          const x = onRejected(this.reason);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      }, 0);
    }

    if (this.status === ‘pending’) {
      this.onFulfilledCallbacks.push(() => {
        setTimeout(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      });

      this.onRejectedCallbacks.push(() => {
        setTimeout(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      });
    }
  });

  return promise2;
};

4. 实现 resolvePromise 辅助函数

这个函数用于处理 then 回调返回值 x 的情况,判断是否为 Promise 或 thenable 对象,决定如何解析并 resolve 或 reject 新的 Promise。

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError(‘Chaining cycle detected’));
  }

  if (x instanceof MyPromise) {
    x.then(y => {
      resolvePromise(promise2, y, resolve, reject);
    }, reject);
  } else if (x !== null && (typeof x === ‘object’ || typeof x === ‘function’)) {
    let then;
    try {
      then = x.then;
    } catch (e) {
      return reject(e);
    }

    if (typeof then === ‘function’) {
      let called = false;
      try {
        then.call(x, y => {
          if (called) return;
          called = true;
          resolvePromise(promise2, y, resolve, reject);
        }, r => {
          if (called) return;
          called = true;
          reject(r);
        });
      } catch (e) {
        if (called) return;
        called = true;
        reject(e);
      }
    } else {
      resolve(x);
    }
  } else {
    resolve(x);
  } }

基本上就这些。只要严格按照 Promise A+ 规范实现 then 方法的处理逻辑,特别是 resolvePromise 中对循环引用、thenable 对象的递归解析,就能写出一个合规的 Promise 库。测试时建议使用 promises-aplus-tests 工具验证是否完全符合规范。

工具 ai Object NULL if foreach 构造函数 try throw catch Error const 递归 循环 undefined function 对象 typeof this promise 异步 prototype

上一篇
下一篇