Promise 实现
1. 核心状态维护
Promise 有三种状态:PENDING、FULFILLED、REJECTED。
必须确保状态转换不可逆。
2. 完整实现 (面试版)
这是一个符合 Promise/A+ 规范的迷你版本,足以应对大部分手写题。
3. 静态方法实现
Promise.resolve
Promise.reject
Promise.all
Promise.all 用于并行执行一组相互依赖的异步任务。只有所有任务都成功时,
返回的 Promise 才会变为 fulfilled,其结果是一个包含所有成功值的数组。
需要注意以下几点:
- 结果数组的顺序与参数的传入顺序一致,与任务的完成顺序无关。
- 参数中的普通值会被当作已成功的 Promise 处理。
- 只要有一个任务失败,返回的 Promise 就会立即变为
rejected,失败原因是该任务的失败原因。 - 其他任务不会因为其中一个任务失败而自动取消,它们仍会继续执行,只是其结果不会再影响
Promise.all。 - 传入空的可迭代对象时,会立即返回一个状态为
fulfilled、结果为[]的 Promise。
它适用于“所有任务必须全部成功,后续流程才能继续”的场景,例如同时请求页面所需的多组基础数据。
Promise.allSettled
Promise.allSettled 同样会并行执行一组异步任务,但它不会因为某个任务失败而提前结束,
而是等待所有任务都完成后,一次性返回每个任务的执行结果。
返回数组中的每一项有两种结构:
- 成功:
{ status: 'fulfilled', value: 成功值 } - 失败:
{ status: 'rejected', reason: 失败原因 }
它有以下特点:
- 返回结果的顺序与参数的传入顺序一致。
- 单个任务失败不会使
Promise.allSettled返回失败。 - 参数中的普通值会被记录为
fulfilled状态。 - 传入空的可迭代对象时,会立即返回一个状态为
fulfilled、结果为[]的 Promise。
它适用于任务彼此独立、需要收集全部执行结果的场景,例如批量上传文件后展示每个文件的成功或失败状态。
Promise.all 与 Promise.allSettled 的核心区别是失败时是否提前结束:前者强调“全部成功”,
适合强依赖任务;后者强调“全部完成”,适合需要汇总结果的独立任务。
Promise.race
Promise.race 返回一个新的 Promise。迭代对象中第一个状态确定的 Promise,
无论成功还是失败,都会决定返回 Promise 的最终状态。
由于 Promise 的状态一旦确定就不能改变,因此只有最先完成的任务能够调用成功。
当传入空的可迭代对象时,循环不会执行,返回的 Promise 会一直保持 pending 状态。
4. 关键考点
- Pending 状态不可逆。
- 异步执行:必须使用
queueMicrotask或setTimeout来保证then回调在当前宏任务之后执行。 - 链式调用:返回一个新的 Promise。
- 值穿透:如果没有传
onFulfilled,需要透传值 (x => x)。

