Appearance
手写 Promise
来源:
js/实现/promise.html,手写实现符合 Promises/A+ 规范的 Promise。
速查导航
- 核心状态 — pending / fulfilled / rejected
- resolve 与 reject — 状态变更与回调触发
- then 方法 — 链式调用与异步执行
- resolvePromise — 链式值解析
- 完整实现 — 可直接运行验证
核心状态
Promise 有三种状态,状态一旦改变就不可逆:
| 状态 | 含义 |
|---|---|
pending | 等待中,可以变为 fulfilled 或 rejected |
fulfilled | 已成功,持有 value |
rejected | 已失败,持有 reason |
resolve 与 reject
js
要点:
- 只有
pending状态才能修改,保证不可逆onFulfilledCallbacks/onRejectedCallbacks存储异步回调shift()逐个取出执行,确保回调按注册顺序触发(shift不是纯函数,取出后数组失去该元素,直到数组为空)
then 方法
then 需要处理三种情况:
- 已 fulfilled → 异步执行成功回调
- 已 rejected → 执行失败回调
- 仍 pending → 暂存回调,等状态变更时执行
js
then(onFulfilled, onRejected) {
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
queueMicrotask(() => {
const x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
});
} else if (this.status === REJECTED) {
onRejected(this.reason);
} else if (this.status === PENDING) {
this.onFulfilledCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}
});
return promise2;
}
queueMicrotask的作用: 确保onFulfilled异步执行,符合 Promises/A+ 规范 2.2.4
resolvePromise
处理 then 回调的返回值,实现链式调用:
js
resolvePromise(promise2, x, resolve, reject) {
// 如果返回自身,抛 TypeError 防止死循环
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
}
// 如果返回的是 Promise,等它决议
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
// 普通值直接 resolve
resolve(x);
}
}完整实现
js
验证要点:
- 输出顺序:
1→resolve: success→2→resolve: success→resolve: success- 同一个 Promise 可以注册多个
then回调- 异步执行(
setTimeout+queueMicrotask)确保回调在微任务队列中触发