新闻中心
实现一个符合Promises/A+规范的Promise类
实现符合Promises/A+规范的Promise类需遵循状态不可逆、then链式调用、异步执行与错误捕获。核心包括:定义pending/fulfilled/rejected三种状态,通过resolve和reject函数变更状态并触发回调;then方法返回新Promise实例,支持onFulfilled与onRejected回调,并使用resolvePromise处理返回值,防止循环引用,递归解析嵌套Promise直至得到最终值。完整实现包含状态管理、回调队列、异步调度及类型安全判断,确保符合规范要求。

要实现一个符合 Promises/A+ 规范的 Promise 类,核心是理解其状态机机制、then 方法的处理逻辑以及异步解析流程。下面是一个简化但完全符合 Promises/A+ 规范的 Promise 实现,包含关键特性:状态管理、then 链式调用、异步执行、错误捕获和 resolvePromise 处理。
基本结构与状态定义
Promise 有三种状态:pending(等待)、fulfilled(成功)、rejected(失败)。一旦状态变更,不可逆。
- 初始状态为 pending
- 通过 resolve 改变为 fulfilled
- 通过 reject 改变为 rejected
- 状态变更后,所有后续的 resolve 或 reject 调用都无效
实现 then 方法
then 方法必须返回一个新的 Promise,以支持链式调用。它接收两个回调函数:onFulfilled 和 onRejected。
- 如果 onFulfilled 是函数,它在 Promise 成功时被调用
- 如果 onRejected 是函数,它在 Promise 失败时被调用
- then 的返回值用于决定新 Promise 的状态,需通过 resolvePromise 函数统一处理
- 支持异步注册,即在 pending 状态下将回调存入队列
处理嵌套 Promise 与 resolvePromise
当 then 的回调返回一个 Promise 时,需要等待其决议结果来决定外层 Promise 的状态。这是 Promises/A+ 的核心规则之一。
resolvePromise 函数的作用是:
BrandCrowd
一个在线Logo免费设计生成器
200
查看详情
- 判断 x 是否为 Promise 实例
- 防止循环引用(如 return self)
- 提取 then 方法并安全调用(防多次调用)
- 递归解析直到得到原始值
完整实现代码
以下是符合 Promises/A+ 规范的简易实现:
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function MyPromise(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 (err) {
reject(err);
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected'));
}
let called = false;
if ((typeof x === 'object' && x !== null) || 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);
}
}
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 (err) {
reject(err);
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
}
if (this.status === PENDING) {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
}
});
return promise2;
};
// 可选:添加 catch 方法
MyPromise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
// 可选:添加静态方法 resolve / reject
MyPromise.resolve = function(value) {
return new MyPromise(resolve => resolve(value));
};
MyPromise.reject = function(reason) {
return new MyPromise((_, reject) => reject(reason));
};
测试示例
验证基本功能:
new MyPromise((resolve) => {
setTimeout(() => resolve('hello'), 100);
})
.then(val => {
console.log(val); // hello
return val + ' world';
})
.then(val => {
console.log(val); // hello world
});
这个实现通过了大部分 Promises/A+ 测试用例(可用 promises-aplus-tests 工具验证),适合学习原理。
基本上就这些,关键是理解状态流转和 resolvePromise 的递归处理逻辑。
以上就是实现一个符合Promises/A+规范的Promise类的详细内容,更多请关注其它相关文章!
# 它与
# 金华全网营销推广系统
# 雅安网络开发网站建设
# 小旋风seo代做
# 海外营销推广行业
# 网站优化seo入门
# 湖南违规建设举报网站
# 什么是营销型网站建设
# 2020做seo谷歌
# 盐城网站建设大概费用
# 品牌营销推广在哪里办公
# 有什么不同
# 回调函数
# 有什么区别
# 如何使用
# 它在
# 可选
# 有何
# 链式
# 回调
# 递归
# ai
# 工具
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
抖音创作助手登录入口_抖音创作辅助工具官网直达
J*aScript实现动态背景色下的文本与按钮颜色自适应调整
使用J*aScript检测输入元素是否包含在特定类中
Pandas DataFrame 多条件优先级排序与排名
Mac怎么使用表情符号_Mac Emoji快捷键面板
css滚动动画效果怎么实现_使用Animate.css滚动触发动画类
Mac怎么查看崩溃日志_Mac控制台错误报告分析
学习通网页版快速入口 学习通官网网页版直接打开
在Go开发中优雅管理ListenAndServe进程:GoSublime集成方案
iwriter统一登录平台 iwrite账号密码登录页面
C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果
J*aScript中安全有效地处理localStorage字符串数据
CSS实现侧边栏导航项全宽圆角悬停背景效果
QQ邮箱网页版入口页面 QQ邮箱在线登录入口官网
在J*a中如何隐藏复杂性_使用门面模式组织对象交互
C++如何解决segmentation fault_C++段错误调试与原因分析
UC浏览器如何安装插件 UC浏览器添加扩展程序详细教程【进阶】
2026春节假期票务安排_2026春节放假购票指南
离线运行Go语言之旅:本地部署与GOPATH配置指南
windows10怎么查看本机ip_windows10命令提示符ipconfig使用
俄罗斯搜索引擎Yandex指南 附2025年免登录官网入口
TypeScript/J*aScript:高效查找数组中首个唯一ID对象
小红书怎么解除第三方平台绑定_小红书多平台登录解绑方法介绍
Golang如何优化CPU绑定任务分配策略_Golang CPU任务分配优化实践
蛙漫移动版在线看 蛙漫手机浏览器直达入口
反效果?《战地6》免费试玩开启后玩家数不升反降
微信商城在哪里打开【步骤】
MAC怎么让Dock栏只显示当前运行的应用_MAC终端命令实现极简Dock栏
如何在CSS中使用浮动制作导航栏_float实现水平菜单
Golang如何实现微服务鉴权与权限控制_Golang微服务鉴权与权限管理实践
LINUX的perf命令入门_LINUX官方性能分析工具的使用与解读
PHP中SSG-WSG API的AES加密实践:正确使用初始化向量
台积电1.4nm工艺A14瞄准2028:10年来性能提升80%
铁路12306改签能改到更早的车次吗_铁路12306改签提前车次规则
小米14应用无法联网原因分析_小米14网络权限修复
谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示
Lar*el 递归关系中排除指定分支的教程
Win11怎么关闭快速启动_Win11彻底关机设置教程
Lar*el头像管理:图片缩放与旧文件删除的最佳实践
Win11怎么安装Linux子系统 Win11 WSL2安装Ubuntu及环境配置指南
处理Kafka消费者会话超时:深入理解消息处理语义与幂等性
使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性
怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法
极兔快递快件信息查询系统 极兔快递官网运单号追踪
海棠电脑版入口_通过电脑访问海棠官网阅读
在Socket.IO连接中实现Access Token自动更新与动态重连
探索高级语言到C/C++的转译路径:以Go为例及内存管理策略
不会效仿卡普空!《铁拳》制作人澄清:不采取赛事付费|直播|
没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享
魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】


2025-11-05
浏览次数:次
返回列表
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
}
if (this.status === PENDING) {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
}
});
return promise2;
};
// 可选:添加 catch 方法
MyPromise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
// 可选:添加静态方法 resolve / reject
MyPromise.resolve = function(value) {
return new MyPromise(resolve => resolve(value));
};
MyPromise.reject = function(reason) {
return new MyPromise((_, reject) => reject(reason));
};