新闻中心

如何实现一个符合Promises/A+规范的Promise库?

2025-10-18
浏览次数:
返回列表
实现符合Promises/A+规范的Promise库需处理状态机、异步解析和链式调用。1. 定义三种不可逆状态:pending、fulfilled、rejected;2. 构造函数中通过resolve/reject控制状态流转并存储回调;3. then方法返回新Promise,根据当前状态异步执行对应回调,并使用queueMicrotask确保异步执行;4. resolvePromise函数处理返回值x,判断是否为thenable或Promise实例,避免循环引用,保证正确决议新Promise。该结构支持链式调用与错误传递,符合核心规范要求。

如何实现一个符合promises/a+规范的promise库?

实现一个符合 Promises/A+ 规范的 Promise 库,核心在于理解并正确处理状态机、异步解析流程和 then 方法的链式调用。下面是一个简化但符合规范关键点的实现思路与代码结构。

1. 理解 Promise 的三种状态

Promise 有三种状态:

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

状态一旦变更,就不能再次修改。then 方法根据当前状态决定执行 onFulfilled 还是 onRejected 回调,并支持异步延迟绑定。

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

定义构造函数和内部状态:

AI Surge Cloud AI Surge Cloud

低代码数据分析平台,帮助企业快速交付深度数据

AI Surge Cloud 87 查看详情 AI Surge Cloud
function MyPromise(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(fn => fn());
    }
  };

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

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

3. 实现 then 方法(核心)

then 方法必须返回一个新的 Promise,以支持链式调用。这是 Promises/A+ 的重点。

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  // 处理回调可选的情况
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
  onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };

  // 返回新 Promise 实现链式调用
  const promise2 = new MyPromise((resolve, reject) => {
    if (this.state === 'fulfilled') {
      queueMicrotask(() => {
        try {
          const x = onFulfilled(this.value);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      });
    }

    if (this.state === 'rejected') {
      queueMicrotask(() => {
        try {
          const x = onRejected(this.reason);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      });
    }

    if (this.state === 'pending') {
      this.onFulfilledCallbacks.push(() => {
        queueMicrotask(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      });

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

  return promise2;
};

4. 实现 resolvePromise 辅助函数

这个函数用于处理 onFulfilled/onRejected 返回值 x 的情况,判断是否为 Promise 实例或 thenable 对象。

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === 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(promise2, 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 可链式调用、兼容 thenable、处理循环引用等。要完全通过官方测试套件(promises-aplus-tests),还需补充一些边界情况,比如参数校验、错误冒泡、多次 resolve/reject 防止重复调用等。

以上就是如何实现一个符合Promises/A+规范的Promise库?的详细内容,更多请关注其它相关文章!


# 相关文章  # 泗塘新村街道网站建设  # 黄石seo推广排名榜  # 武城网站优化在线咨询  # php 开源seo系统  # 玉溪制造业营销推广方案  # 合肥公司网站推广品牌  # 卤菜营销推广方案  # 优化网站只选c火28星细心  # 南通seo优化套餐  # 全网营销推广哪种渠道好  # ai  # 视频编辑  # 这是  # 是一个  # 判断是否  # 返回值  # 三种  # 如何实现  # 回调  # 链式 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构  美团外卖商家服务中心入口 美团商家版官网入口  在命令行怎么运行html项目_命令行运行html项目方法【教程】  HTML长属性值处理:表单action路径优化与代码规范应对  MAC怎么安装Homebrew包管理器_MAC为开发者和高级用户安装命令行工具  Android Studio计算器C键逻辑错误排查与修复:条件判断优化指南  妖精动漫免费平台 妖精动漫官网资源观看网址  html两个JS只运行一个怎么办_让双JS在html中都运行方法【技巧】  React Hooks最佳实践:动态组件状态管理的组件化方案  动漫共和国防屏蔽稳定域名-动漫共和国官方正版直达通道  修复二维数组索引越界异常:一维循环到二维坐标的正确映射  Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明  中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】  聚水潭ERP登录页面入口 聚水潭ERP官网登录界面  word中如何让数字纵向排列_Word数字纵向排列方法  58动漫网在线官方网 58动漫网正版动漫入口网址  cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法  谷歌浏览器如何快速清除某个网站的数据_Chrome网站缓存清理方法  Go调试环境为何无法启动_Go调试器启动失败原因与解决策略  黑猫投诉统一入口官网 消费者权益保护投诉平台  Win10桌面图标出现小盾牌怎么办 Win10去除UAC图标教程【解决】  Win10怎么制作U盘启动盘 Win10系统安装U盘制作教程【详解】  Lar*el头像管理:图片缩放与旧文件删除的最佳实践  Win10自动更新怎么关闭 Win10永久关闭系统更新的两种方法【终极版】  c++ 获取系统当前时间 c++时间戳获取方法  Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区  夸克浏览器图书入口 夸克手机浏览器阅读入口  谷歌浏览器一键优化方案_谷歌浏览器直达主页极速不卡版  微信语音通话掉线如何解决 微信语音通话稳定优化方法  J*aScriptWebpack优化_J*aScript构建工具实战  PHP 枚举:根据字符串获取枚举案例的策略与实现  Lar*el如何生成PDF或Excel文件_Lar*el文档导出工具与使用教程  在J*a中如何开发在线活动报名与管理系统_活动报名管理项目实战解析  蛙漫2日版入口 WAMAN2(日版)无删减漫画官网链接  神经网络二分类模型训练异常:高损失与完美验证准确率的排查与修正  composer 和 npm/yarn 在管理依赖方面有什么核心思想差异?  J*aScript动态修改指定div内所有a标签样式指南  Kafka Streams中基于消息头条件过滤消息的实现指南  DLsite中文平台入口 DLsite官网内容在线查看  b站赚钱渠道_b站收益来源  QQ邮箱在线使用入口 QQ邮箱个人账号网页版登录  J*aScript Promise链中如何正确终止后续.then执行并处理错误  c++如何使用Meson构建系统_c++比CMake更快的构建工具  win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】  MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具  《刺客信条:影》PS5 Pro和Switch 2画面对比  age动漫网站入口 age动漫官网直接访问入口  PHP中高效并行检查多链接状态的教程  铁路12306官网网页端快速入口 铁路12306官方首页登录教程  微博网页版首页入口 微博电脑端官网登录链接 

搜索