MyPromise
手动实现的 Promise,符合 Promises/A+ 规范。完全不依赖原生 Promise,通过依赖注入实现微任务调度。
前置依赖
依赖参数
| 参数名 | 类型 | 说明 |
|---|---|---|
deps.scheduleMicrotask | (callback: () => void) => void | 微任务调度函数 |
环境要求
不同环境需要提供合适的微任务调度函数:
Node.js 环境:
typescript
const deps = {
scheduleMicrotask: (callback: () => void) => {
if (typeof process !== 'undefined' && process.nextTick) {
process.nextTick(callback)
} else {
setTimeout(callback, 0)
}
}
}浏览器环境:
typescript
const deps = {
scheduleMicrotask: (callback: () => void) => {
if (typeof queueMicrotask !== 'undefined') {
queueMicrotask(callback)
} else {
setTimeout(callback, 0)
}
}
}函数签名
typescript
interface MyPromiseDeps {
/** 微任务调度函数 */
scheduleMicrotask: (callback: () => void) => void
}
class MyPromise<T> {
constructor(
executor: (resolve: (value: T) => void, reject: (reason: any) => void) => void,
deps: MyPromiseDeps
)
then<R1 = T, R2 = never>(
onFulfilled?: (value: T) => R1,
onRejected?: (reason: any) => R2
): MyPromise<R1 | R2>
catch<R = never>(onRejected?: (reason: any) => R): MyPromise<T | R>
finally(onFinally?: () => void): MyPromise<T>
static resolve<T>(value: T | PromiseLike<T>, deps: MyPromiseDeps): MyPromise<T>
static reject<T = never>(reason: any, deps: MyPromiseDeps): MyPromise<T>
static all<T>(promises: Array<T | PromiseLike<T>>, deps: MyPromiseDeps): MyPromise<T[]>
static race<T>(promises: Array<T | PromiseLike<T>>, deps: MyPromiseDeps): MyPromise<T>
static allSettled<T>(promises: Array<T | PromiseLike<T>>, deps: MyPromiseDeps): MyPromise<Array<PromiseSettledResult<T>>>
static any<T>(promises: Array<T | PromiseLike<T>>, deps: MyPromiseDeps): MyPromise<T>
}参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
executor | (resolve, reject) => void | 是 | Promise 执行器函数,接收 resolve 和 reject 回调 |
deps | MyPromiseDeps | 是 | 依赖注入对象,包含微任务调度函数 |
返回值
| 类型 | 说明 |
|---|---|
MyPromise<T> | Promise 实例 |
工作原理
状态管理
- Promise 有三种状态:
pending、fulfilled、rejected - 状态只能从
pending转换到其他状态一次,且不可逆 - 通过依赖注入
deps接收微任务调度函数
- Promise 有三种状态:
then 方法
- 返回新的
MyPromise实例,支持链式调用 - 如果当前 Promise 已完成,立即异步执行回调
- 如果当前 Promise 未完成,将回调存储到队列中
- 使用
deps.scheduleMicrotask调度微任务 - 新的 Promise 会继承父 Promise 的 deps
- 返回新的
Promise 解析
- 处理返回值是 Promise 的情况(Promise 链)
- 处理 thenable 对象(有 then 方法的对象)
- 检测并防止循环引用(
promise2 === x) - 确保 resolve/reject 只调用一次
静态方法
- 所有静态方法都需要传入
deps参数 resolve: 快速创建已解析的 Promisereject: 快速创建已拒绝的 Promiseall: 等待所有 Promise 完成race: 返回第一个完成的 PromiseallSettled: 等待所有 Promise 完成,无论成功或失败any: 返回第一个成功的 Promise
- 所有静态方法都需要传入
环境无关性
- 不依赖原生 Promise,完全手写实现
- 通过依赖注入适配不同环境的微任务调度
- Node.js 使用
process.nextTick,浏览器使用queueMicrotask - 降级到
setTimeout以兼容更多环境
这是 Promises/A+ 规范的完整实现,是前端最重要的面试题之一。