符合 Promises/A+ 规范的自定义 Promise 必须严格遵循状态不可逆、executor 同步执行与异常捕获、then 多次注册与微任务调度、链式返回新 Promise 及值穿透等核心约束。

要编写一个符合 Promises/A+ 规范的自定义 Promise,核心不是“写个能用的异步容器”,而是严格遵循规范中对状态、执行时机、链式调用、错误传播等行为的约束。它不是语法糖,而是一套可预测、可互操作的契约。
明确 Promise 的三种不可逆状态
Promise 必须只存在 pending(等待)、fulfilled(已成功)、rejected(已失败)三种状态,且状态只能从 pending 单向流转到 fulfilled 或 rejected,不可回退或二次变更。
- 初始化时 status = 'pending',value 和 reason 初始为 undefined 或 null
- resolve(value) 只在 status === 'pending' 时才更新状态和 value,并触发所有已注册的成功回调
- reject(reason) 同理,仅在 pending 下生效,设置 reason 并触发失败回调
- 一旦 fulfilled 或 rejected,后续所有 resolve/reject 调用均被忽略
正确实现 executor 执行器与异常捕获
构造函数接收的 executor 函数必须同步立即执行,且其内部抛出的任何错误都应自动触发 reject。
- executor 是形参函数,接收 resolve 和 reject 两个函数作为参数
- 必须用 try/catch 包裹 executor 调用,捕获同步异常并传给 reject
- resolve 和 reject 需绑定 this,确保内部 this 指向当前 Promise 实例
- 不能让 resolve/reject 成为裸函数调用,否则 this 丢失导致状态无法更新
支持多次 then 注册与异步回调队列
当 Promise 处于 pending 状态时,调用 then 应缓存回调;待状态确定后,再按注册顺序依次执行对应队列(onFulfilledCallbacks / onRejectedCallbacks)。
立即学习“Java免费学习笔记(深入)”;
- 每个 Promise 实例需维护两个数组:存放成功回调和失败回调
- then 方法内判断当前状态:若 pending,推入对应队列;若已 fulfilled/rejected,立即异步执行(用 queueMicrotask 或 Promise.resolve().then)以保证微任务顺序
- 回调执行时需传递 value 或 reason,并处理返回值——这是链式调用的基础
实现 then 的链式返回与值穿透逻辑
then 必须返回一个新的 Promise 实例,而非 this;且需根据上层回调的返回值决定下层 Promise 的状态。
- 返回值为 Promise,则新 Promise 的状态由该 Promise 决定(即“扁平化”)
- 返回值为普通值(非 Promise、非 thenable),则新 Promise 以该值 fulfilled
- 回调中 throw 错误或返回被 reject 的 Promise,新 Promise 就 rejected
- 拒绝态的 then 若未提供 onRejected,错误会继续向下传递(隐式 catch)
不复杂但容易忽略:微任务调度、thenable 判断、resolvePromise 递归展开、以及对 resolve(x) 中 x === promise 自引用的循环检测——这些细节正是 Promises/A+ 测试套件(如 promises-aplus-tests)验证的重点。真正合规的实现,靠的是逐条对照规范,而非仅让代码“看起来能跑”。


















