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

要实现一个符合 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,以支持链式调用。
青泥AI
青泥学术AI写作辅助平台
360
查看详情
关键点包括:
- 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 类?的详细内容,更多请关注其它相关文章!
# 链式
# 网站建设与设计的关系
# 亚马逊a9关键词系统排名操作
# 常州seo整站优化
# 郑州搜索关键词排名软件
# 三种
# 中文网
# 相关文章
# 就不
# 视频编辑
# 是一个
# 返回值
# 可选
# 回调
# ai
# 南昌网站优化搜索
# 磁县营销推广招聘信息网
# 马拉松营销推广活动方案
# 湖北医院网站建设
# 济南seo优化哪家强
# 谷歌产品营销推广
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
sublime侧边栏怎么增强功能_SideBarEnhancements for sublime安装与配置
Win10自动更新怎么关闭 Win10永久关闭系统更新的两种方法【终极版】
Lar*el Form Request中唯一性验证在更新操作中的正确实现
处理嵌套交互式控件:前端可访问性指南
c++如何使用chrono库处理时间_c++标准库时间与日期操作
我的世界官方游戏入口 我的世界官网平台直达链接
妖精动漫免费平台 妖精动漫官网资源观看网址
AO3中文官网链接_AO3网页版稳定镜像站
Python Socket多播通信中指定源IP地址的实践指南
J*aScript类型检查_j*ascript代码规范
Gmail邮箱申请注册直达_Gmail邮箱免费注册PC版官网入口2025
《燕云十六声》两周内达九百万玩家!位居畅销榜第五
Python:递归比较文件夹内容并找出特定类型文件的差异
Win11怎么开启高性能模式_Windows 11电源计划优化设置
Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达
虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画
QQ邮箱官网登录入口 QQ邮箱网页版邮箱快速登录
顺丰快递查单号物流信息 顺丰快递小程序查询入口
C++ string find函数返回值npos详解_C++字符串查找失败的判断条件
mysql备份恢复性能优化_mysql备份恢复性能优化方法
BetterDiscord插件中安全更新用户简介的实践指南
TikTok评论显示延迟如何处理 TikTok评论刷新优化方法
“在文档元素之后找到了标记”是什么错误? 检查并修复XML中多个根元素的3个方法
Django表单提交验证失败后保持字段值不刷新
海量存储:机器视觉智能化的核心基石
京东京造J1和网易云音乐氧气真无线有什么不同_国产电商蓝牙耳机音质对比
AO3官方在线访问地址 Archive of Our Own最新镜像合集
内存检查:在VS Code中调试C++时的内存视图
LINUX怎么设置定时任务_LINUX crontab配置教程
TikTok搜索不到用户发布内容怎么办 TikTok用户内容搜索优化方法
谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示
押井守高度称赞《辐射4》:玩了八年都停不下来!
斑马英语APP如何开启夜间护眼阅读_斑马英语APP夜间模式与低蓝光设置教程
海棠账号登录入口_登录海棠账户同步阅读记录
单12V-2×6实现为RTX 5090供电750W!甚至都没敢跑分
小红书商家版怎样在笔记嵌入商品卡路径_小红书商家版在笔记嵌入商品卡路径【挂载教程】
Win11怎么安装Linux子系统 Win11 WSL2安装Ubuntu及环境配置指南
单射、满射与双射的关系 一文理清所有逻辑
腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录
零跑汽车11月交付量达70327台 实现连续9个月正增长
怎么在mac上运行html代码_mac运行html代码方法【指南】
我的世界mc.js免费游戏直接能玩 我的世界mc.js小游戏免费秒玩入口
Lar*el Excel导入时生成自定义递增ID的策略与实践
Go语言中对Map值调用带指针接收者方法:原理与最佳实践
HTML空白字符处理机制:渲染、DOM与编码实践
uc浏览器网页版极速入口 uc网页浏览器网页版流畅体验
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
必由学在线入口 必由学网页版快速登录入口
steam官方网页快速访问 steam账号注册全流程
深入理解与实现最大堆的Heapify过程:常见错误与修正


2025-10-10
浏览次数:次
返回列表
=== '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;
}