首页 > web前端 > js教程 > 正文

怎样实现一个符合 Promises/A+ 规范的 Promise 类?

紅蓮之龍
发布: 2025-10-10 17:53:01
原创
835人浏览过
实现符合 Promises/A+ 规范的 Promise 类需掌握其核心机制:1. 状态不可逆(pending → fulfilled/rejected);2. 构造函数立即执行 executor 并接收 resolve/reject 函数;3. then 方法返回新 Promise,支持链式调用;4. 回调通过 queueMicrotask 异步执行;5. resolvePromise 解析返回值,处理对象或函数的 thenable 行为;6. 检测循环引用。该实现涵盖状态管理、异步延迟、错误捕获与链式传递,基本通过 A+ 测试。

怎样实现一个符合 promises/a+ 规范的 promise 类?

要实现一个符合 Promises/A+ 规范的 Promise 类,核心是理解其状态机制、then 方法的处理逻辑以及异步解析流程。下面是一个精简但完整、符合规范关键点的实现。

Promise 的三种状态

Promise 有三种状态:

  • pending:初始状态,可变
  • fulfilled:成功状态,不可逆
  • rejected:失败状态,不可逆

状态一旦从 pending 变为 fulfilled 或 rejected,就不能再改变。

构造函数与状态管理

创建 Promise 实例时,传入一个执行器函数(executor),它立即执行,并接收 resolve 和 reject 两个函数作为参数。

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

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

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

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
}
登录后复制

实现 then 方法

then 方法用于注册成功和失败的回调,且必须返回一个新的 Promise,以支持链式调用。

Onlook
Onlook

专为前端设计师和开发者打造的视觉编辑工具

Onlook 108
查看详情 Onlook

关键点包括:

  • onFulfilled 和 onRejected 是可选函数
  • 回调必须异步延迟执行(使用 queueMicrotask 或 setTimeout)
  • 处理返回值 x,调用 resolvePromise 进行解析
then(onFulfilled, onRejected) {
  // 处理可选参数
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
  onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };

  // 返回新的 Promise 实现链式调用
  const promise2 = new MyPromise((resolve, reject) => {
    const handleCallback = (callback, status, data) => {
      queueMicrotask(() => {
        try {
          const x = callback(data);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      });
    };

    if (this.status === 'fulfilled') {
      handleCallback(onFulfilled, this.status, this.value);
    } else if (this.status === 'rejected') {
      handleCallback(onRejected, this.status, this.reason);
    } else {
      // pending 状态,缓存回调
      this.onFulfilledCallbacks.push(() => handleCallback(onFulfilled, 'fulfilled', this.value));
      this.onRejectedCallbacks.push(() => handleCallback(onRejected, 'rejected', this.reason));
    }
  });

  return promise2;
}
登录后复制

resolvePromise 辅助函数

这个函数决定如何根据 x 的类型来 resolve 新的 Promise,是 Promises/A+ 的核心逻辑之一。

function resolvePromise(promise, x, resolve, reject) {
  if (promise === x) {
    return reject(new TypeError('Chaining cycle detected'));
  }

  let called = false;

  if (x != null && (typeof x === 'object' || typeof x === 'function')) {
    try {
      const then = x.then;
      if (typeof then === 'function') {
        then.call(
          x,
          y => {
            if (called) return;
            called = true;
            resolvePromise(promise, y, resolve, reject);
          },
          r => {
            if (called) return;
            called = true;
            reject(r);
          }
        );
      } else {
        resolve(x);
      }
    } catch (e) {
      if (called) return;
      called = true;
      reject(e);
    }
  } else {
    resolve(x);
  }
}
登录后复制

基本上就这些。这个实现涵盖了 Promises/A+ 的主要要求:状态管理、then 链式调用、异步执行、错误捕获和循环引用检测。虽然省略了一些边界情况的极致优化,但它能通过大部分 A+ 测试套件(如 promises-aplus-tests)。

以上就是怎样实现一个符合 Promises/A+ 规范的 Promise 类?的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号