1166 字
6 分钟
JavaScript 实现 Promise A+ 规范

题目描述
实现 Promise A+ 规范
解题思路
- 状态机设计:Promise 必须实现三种状态(pending/fulfilled/rejected)的状态转换机制
- 异步处理:then 方法需要支持异步调用,回调需放入微任务队列
- 链式调用:then 方法必须返回新 Promise 实现链式调用
- 值穿透:当 then 参数不是函数时需要实现值穿透
- 错误处理:需要捕获执行器函数和回调函数中的错误
- 解决程序:实现复杂的 Promise 解决程序处理 thenable 对象
关键洞察
- 状态不可逆性 Promise 状态只能从 pending 转为 fulfilled/rejected,且不可逆转,这是异步操作确定性的基础保障
- 微任务调度机制 所有回调必须通过微任务(queueMicrotask)执行,确保在同步代码之后、渲染之前执行,保证执行时序正确性
- 递归解析协议 通过 resolvePromise 函数递归处理 thenable 对象,兼容各种 Promise 实现,这是 A+ 规范的核心要求
- 链式传播机制 每个 then 都返回新 Promise,形成独立状态链,实现值/异常的逐级传递和错误冒泡处理
- 安全防护设计 循环引用检测防止无限递归,called 标志位防止多次调用,确保程序的健壮性和可靠性
- 值穿透实现原理 非函数参数时创建默认回调函数:
value => value
和reason => { throw reason }
,实现值/异常的自动传递
设计本质:状态机 + 回调队列 + 递归解析,通过 15 条规范解决异步编程的时序控制、错误处理、值传递等核心问题
代码流程
flowchart TD A[new Promise] --> B[执行executor] B -->|resolve| C[状态改为fulfilled] B -->|reject| D[状态改为rejected] C --> E[执行onFulfilled回调] D --> F[执行onRejected回调] E --> G[处理返回值] F --> G G --> H[根据返回值处理新Promise] H --> I[链式调用]
代码实现
const PENDING = "PENDING";const FULFILLED = "FULFILLED";const REJECTED = "REJECTED";
function isObject(value) { const type = typeof value; return value !== null && (type === "function" || type === "object");}
function resolvePromise(promise, x, resolve, reject) { if (promise === x) { reject(new TypeError("Chaining cycle detected the promise #<Promise>")); }
if (isObject(x)) { var then;
try { then = x.then; } catch (error) { reject(error); }
if (typeof then === "function") { var called = false;
try { then.call( x, (y) => { if (called) return; called = true; resolvePromise(promise, y, resolve, reject); }, (r) => { if (called) return; called = true; reject(r); } ); } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } } else { resolve(x); }}
class MyPromise { status = PENDING; data = null; #onFulfilledCallbacks = []; #onRejectedCallbacks = [];
#resolve = (value) => { if (this.status === PENDING) { this.status = FULFILLED; this.data = value; while (this.#onFulfilledCallbacks.length) { this.#onFulfilledCallbacks.shift()(value); } } };
#reject = (reason) => { if (this.status === PENDING) { this.status = REJECTED; this.data = reason; while (this.#onRejectedCallbacks.length) { this.#onRejectedCallbacks.shift()(reason); } } };
constructor(executor) { try { executor(this.#resolve, this.#reject); } catch (error) { this.#reject(error); } }
then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value; onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason; };
const promise = new MyPromise((resolve, reject) => { const resolved = () => { queueMicrotask(() => { try { const x = onFulfilled(this.data); resolvePromise(promise, x, resolve, reject); } catch (error) { reject(error); } }); };
const rejected = () => { queueMicrotask(() => { try { const x = onRejected(this.data); resolvePromise(promise, x, resolve, reject); } catch (error) { reject(error); } }); };
if (this.status === PENDING) { this.#onFulfilledCallbacks.push(resolved); this.#onRejectedCallbacks.push(rejected); }
if (this.status === FULFILLED) { resolved(); }
if (this.status === REJECTED) { rejected(); } });
return promise; }
catch(onRejected) { return this.then(undefined, onRejected); }
finally(onFinally) { return this.then( (value) => MyPromise.resolve(onFinally()).then(() => value), (reason) => MyPromise.resolve(onFinally()).then(() => { throw reason; }) ); }
static resolve(value) { return new MyPromise((resolve, reject) => { value instanceof MyPromise ? value.then(resolve, reject) : resolve(value); }); }
static reject(reason) { return new MyPromise((resolve, reject) => { reject(reason); }); }
static withResolver() { const result = {}; result.promise = new MyPromise(($$resolve, $$reject) => { result.resolve = $$resolve; result.reject = $$reject; }); return result; }}
业务场景
- 异步流程控制:解决回调地狱,使异步代码更清晰
- 接口请求顺序:处理多个接口的串行/并行请求
- 错误统一处理:通过 catch 统一捕获整个链中的错误
- 数据依赖处理:处理前后端数据依赖关系
- 微任务调度:在渲染前执行关键逻辑(如状态更新)
性能考量: Promise 实现需要高效的微任务调度机制 避免深层递归导致的栈溢出 内存管理(及时清理回调队列)
相似题目
- 实现 Promise.all(难度:中等)
- 核心:处理多个 Promise 的并行执行
- 实现 Promise.race(难度:中等)
- 核心:首个 Promise 完成即返回
- 实现 Promise.allSettled(难度:中等)
- 核心:收集所有 Promise 的最终状态
- 实现 async/await(难度:困难)
- 核心:Generator + Promise 的语法糖实现
- 实现并发控制器(难度:困难)
- 核心:Promise + 队列控制并发数量
JavaScript 实现 Promise A+ 规范
https://website-truelovings-projects.vercel.app/posts/code/javascript/javascript-实现-promise-a-规范/