TS分步实现Promise A+规范
参考文章&本文介绍
手把手一行一行代码教你“手写Promise“,完美通过 Promises/A+ 官方872个测试用例手写 Promise - 掘金
这篇文章从Promise A+规范每一条的角度出发,能清晰的看出每段代码与规范对应的地方;
本文主要是从一个简单的demo出发,一步一步有比较的、有使用示例的完善,到最后实现Promise A+规范
分步实现
1.Promise的三种状态、完成值、执行器方法
- 只实现了 status、resolve/reject、执行器立即执行
- 能记录 pending/fulfilled/rejected 三种状态
- 但还不能链式调用和处理回调
// 1. Promise的三种状态、完成值、执行器方法
type Status = 'pending' | 'fulfilled' | 'rejected';
type Executor<T> = (resolve: Resolve<T>, reject: Reject) => void;
type Resolve<T> = (result?: T) => void;
type Reject = (reason?: any) => void;
class MyPromise<T> {
status: Status = 'pending';
private fulfilledValue?: T;
private rejectionReason?: any;
constructor(executor?: Executor<T>) {
executor?.(this.resolve, this.reject);
}
private resolve: Resolve<T> = (result?: T) => {
if (this.status !== 'pending') return;
this.fulfilledValue = result;
this.status = 'fulfilled';
};
private reject: Reject = (reason?: any) => {
if (this.status !== 'pending') return;
this.rejectionReason = reason;
this.status = 'rejected';
};
}
const p1 = new MyPromise(); // pending
const p2 = new MyPromise((resolve) => {
resolve();
}); // fulfilled
const p3 = new MyPromise<void>((_, reject) => {
reject();
}); // rejected
const p4 = new MyPromise<string>((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.9) {
resolve('F');
} else {
reject('R');
}
}, 1000);
}); // pending -> fulfilled or rejected
setTimeout(() => {
console.log(p1, p2, p3, p4);
}, 1000);
export {};
2.实现then方法的链式调用
- 引入 then
- 增加回调队列(pending 时缓存)
- 开始支持链式调用
- 还没细致处理回调返回值,也没有微任务。

// 2. 实现then方法的链式调用
type Status = 'pending' | 'fulfilled' | 'rejected';
type Executor<T> = (resolve: Resolve<T>, reject: Reject) => void;
type Resolve<T> = (result?: T) => void;
type Reject = (reason?: any) => void;
type Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => MyPromise<T>;
class MyPromise<T> {
status: Status = 'pending';
private fulfilledValue?: T;
private rejectionReason?: any;
private onFulfilledCbList: ((result?: T) => any)[] = [];
private onRejectedCbList: ((reason?: any) => any)[] = [];
constructor(executor?: Executor<T>) {
executor?.(this.resolve, this.reject);
}
private resolve: Resolve<T> = (result?: T) => {
if (this.status !== 'pending') return;
this.fulfilledValue = result;
this.status = 'fulfilled';
this.onFulfilledCbList.forEach((cb) => cb());
};
private reject: Reject = (reason?: any) => {
if (this.status !== 'pending') return;
this.rejectionReason = reason;
this.status = 'rejected';
this.onRejectedCbList.forEach((cb) => cb());
};
then: Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => {
const promise2 = new MyPromise<T>((resolve, reject) => {
let hasOnFulfilled = typeof onFulfilled === 'function';
let hasOnRejected = typeof onRejected === 'function';
let isFulfilled = this.status === 'fulfilled';
let isRejected = this.status === 'rejected';
let isPending = this.status === 'pending';
if (isPending) {
// 处理待处理promise的成功回调
this.onFulfilledCbList.push(() => {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
resolve(this.fulfilledValue); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
});
// 处理待处理promise的失败回调
this.onRejectedCbList.push(() => {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
});
} else if (isFulfilled) {
// 处理已成功promise的回调
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
resolve(this.fulfilledValue); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
} else if (isRejected) {
// 处理已失败promise的回调
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
}
});
return promise2;
};
}
const p1 = new MyPromise(); // pending
const p2 = new MyPromise((resolve) => {
resolve();
}); // fulfilled
const p3 = new MyPromise<void>((_, reject) => {
reject();
}); // rejected
const p4 = new MyPromise<string>((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('F');
} else {
reject('R');
}
}, 1000);
}); // pending -> fulfilled or rejected
const p5 = p2
.then(() => {
return 1;
})
.then(() => {
return 2;
}); // 2
const p6 = p4.then(
(res) => {
return 'p6-' + res;
},
(res) => {
return 'p6-' + res;
}
); // 'p6-F' or 'p6-R'
setTimeout(() => {
console.log(p1, p2, p3, p4, p5, p6);
}, 1000);
export {};
3.入微任务队列
- 统一把所有 then 回调包装在 queueMicrotask,确保回调总在同步代码之后执行,以模拟原生 Promise 的微任务调度。

// 3. 入微任务队列
type Status = 'pending' | 'fulfilled' | 'rejected';
type Executor<T> = (resolve: Resolve<T>, reject: Reject) => void;
type Resolve<T> = (result?: T) => void;
type Reject = (reason?: any) => void;
type Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => MyPromise<T>;
class MyPromise<T> {
status: Status = 'pending';
private fulfilledValue?: T;
private rejectionReason?: any;
private onFulfilledCbList: ((result?: T) => any)[] = [];
private onRejectedCbList: ((reason?: any) => any)[] = [];
constructor(executor?: Executor<T>) {
executor?.(this.resolve, this.reject);
}
private resolve: Resolve<T> = (result?: T) => {
if (this.status !== 'pending') return;
this.fulfilledValue = result;
this.status = 'fulfilled';
this.onFulfilledCbList.forEach((cb) => cb());
};
private reject: Reject = (reason?: any) => {
if (this.status !== 'pending') return;
this.rejectionReason = reason;
this.status = 'rejected';
this.onRejectedCbList.forEach((cb) => cb());
};
then: Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => {
const promise2 = new MyPromise<T>((resolve, reject) => {
let hasOnFulfilled = typeof onFulfilled === 'function';
let hasOnRejected = typeof onRejected === 'function';
let isFulfilled = this.status === 'fulfilled';
let isRejected = this.status === 'rejected';
let isPending = this.status === 'pending';
if (isPending) {
// 处理待处理promise的成功回调
this.onFulfilledCbList.push(() => {
queueMicrotask(() => {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
resolve(this.fulfilledValue); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
});
});
// 处理待处理promise的失败回调
this.onRejectedCbList.push(() => {
queueMicrotask(() => {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
});
});
} else if (isFulfilled) {
// 处理已成功promise的回调
queueMicrotask(() => {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
resolve(this.fulfilledValue); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
});
} else if (isRejected) {
// 处理已失败promise的回调
queueMicrotask(() => {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolve(x); // 此处简化了then的返回值的处理,只处理了返回值为普通值的情况
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
});
}
});
return promise2;
};
}
const p1 = new MyPromise(); // pending
const p2 = new MyPromise((resolve) => {
resolve();
}); // fulfilled
const p3 = new MyPromise<void>((_, reject) => {
reject();
}); // rejected
const p4 = new MyPromise<string>((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('F');
} else {
reject('R');
}
}, 1000);
}); // pending -> fulfilled or rejected
const p5 = p2
.then(() => {
return 1;
})
.then(() => {
return 2;
}); // 2
const p6 = p4.then(
(res) => {
return 'p6-' + res;
},
(res) => {
return 'p6-' + res;
}
); // 'p6-F' or 'p6-R'
new MyPromise<string>((resolve) => resolve('micro')).then((val) => {
console.log('then 回调(应在微任务阶段执行)', val);
});
console.log('同步日志(应先输出)');
setTimeout(() => {
console.log(p1, p2, p3, p4, p5, p6);
}, 1000);
export {};
4.实现根据onFulfilled、onRejected的返回值,处理then方法返回的Promise。实现状态吸收
- 引入 resolvePromise2 处理 then 回调的返回值(普通值、Promise、不包括 thenable对象)
- 实现状态吸收(链式调用能正确转化嵌套 promise)
- 解决循环引用问题。

// 4. 实现根据onFulfilled、onRejected的返回值,处理then方法返回的Promise。实现状态吸收
type Status = 'pending' | 'fulfilled' | 'rejected';
type Executor<T> = (resolve: Resolve<T>, reject: Reject) => void;
type Resolve<T> = (result?: T) => void;
type Reject = (reason?: any) => void;
type Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => MyPromise<T>;
class MyPromise<T> {
status: Status = 'pending';
private fulfilledValue?: T;
private rejectionReason?: any;
private onFulfilledCbList: ((result?: T) => any)[] = [];
private onRejectedCbList: ((reason?: any) => any)[] = [];
constructor(executor?: Executor<T>) {
executor?.(this.resolve, this.reject);
}
private resolve: Resolve<T> = (result?: T) => {
if (this.status !== 'pending') return;
this.fulfilledValue = result;
this.status = 'fulfilled';
this.onFulfilledCbList.forEach((cb) => cb());
};
private reject: Reject = (reason?: any) => {
if (this.status !== 'pending') return;
this.rejectionReason = reason;
this.status = 'rejected';
this.onRejectedCbList.forEach((cb) => cb());
};
then: Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => {
const promise2 = new MyPromise<T>((resolve, reject) => {
let hasOnFulfilled = typeof onFulfilled === 'function';
let hasOnRejected = typeof onRejected === 'function';
let isFulfilled = this.status === 'fulfilled';
let isRejected = this.status === 'rejected';
let isPending = this.status === 'pending';
if (isPending) {
// 处理待处理promise的成功回调
this.onFulfilledCbList.push(() => {
queueMicrotask(() => {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue as T);
resolvePromise2(promise2, resolve, reject, x);
} else {
resolve(this.fulfilledValue as T); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
});
});
// 处理待处理promise的失败回调
this.onRejectedCbList.push(() => {
queueMicrotask(() => {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolvePromise2(promise2, resolve, reject, x);
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
});
});
} else if (isFulfilled) {
// 处理已成功promise的回调
queueMicrotask(() => {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue as T);
resolvePromise2(promise2, resolve, reject, x);
} else {
resolve(this.fulfilledValue as T); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
});
} else if (isRejected) {
// 处理已失败promise的回调
queueMicrotask(() => {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolvePromise2(promise2, resolve, reject, x);
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
});
}
});
return promise2;
};
}
function resolvePromise2<T>(promise2: MyPromise<T>, resolve: Resolve<T>, reject: Reject, x: any): void {
if (promise2 === x) {
/**
* 防止这种情况出现
* const p2 = new MyPromise((resolve) => resolve()).then(() => p2);
*/
throw new TypeError('Chaining cycle detected for promise');
}
if (x instanceof MyPromise) {
// Promise对象
x.then((y) => resolvePromise2(promise2, resolve, reject, y), reject); // 如果内层Promise是成功状态,则继续递归
} else if (x && isThisType(x.then, 'Function')) {
// thenable对象
x.then((y: any) => resolvePromise2(promise2, resolve, reject, y), reject); // 此处简化了对thenable对象的处理,只处理了用户调用一次resolve或者reject的情况
} else {
// 普通值
resolve(x);
}
}
function isThisType(x: any, type: string): boolean {
return Object.prototype.toString.call(x) === `[object ${type}]`;
}
const p1 = new MyPromise(); // pending
const p2 = new MyPromise((resolve) => {
resolve();
}); // fulfilled
const p3 = new MyPromise<void>((_, reject) => {
reject();
}); // rejected
const p4 = new MyPromise<string>((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('F');
} else {
reject('R');
}
}, 1000);
}); // pending -> fulfilled or rejected
const p5 = p2
.then(() => {
return 1;
})
.then(() => {
return 2;
}); // 2
const p6 = p4.then(
(res) => {
return 'p6-' + res;
},
(res) => {
return 'p6-' + res;
}
); // 'p6-F' or 'p6-R'
new MyPromise<string>((resolve) => resolve('micro')).then((val) => {
console.log('then 回调(应在微任务阶段执行)', val);
});
console.log('同步日志(应先输出)');
const p7 = p2.then(() => new MyPromise((resolve) => resolve('inner promise'))); // inner promise
setTimeout(() => {
console.log(p1, p2, p3, p4, p5, p6, p7);
}, 1000);
export {};
5.添加错误处理、对于thenable对象的特殊处理
- 添加异常处理
- 添加thenable处理:
- thenable 的 then 读取和执行都要安全且只能 settle 一次(示例演示 tricky thenable 的行为)

// 5. 添加错误处理、对于thenable对象的特殊处理
type Status = 'pending' | 'fulfilled' | 'rejected';
type Executor<T> = (resolve: Resolve<T>, reject: Reject) => void;
type Resolve<T> = (result?: T | Thenable<T>) => void;
type Reject = (reason?: any) => void;
type Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => MyPromise<T>;
type Thenable<T> = {
then(resolve: Resolve<T>, reject: Reject): void;
};
class MyPromise<T> {
status: Status = 'pending';
private fulfilledValue?: T | Thenable<T>;
private rejectionReason?: any;
private onFulfilledCbList: ((result?: T) => any)[] = [];
private onRejectedCbList: ((reason?: any) => any)[] = [];
constructor(executor?: Executor<T>) {
try {
executor?.(this.resolve, this.reject);
} catch (error) {
this.reject(error as any);
}
}
private resolve: Resolve<T> = (result?: T | Thenable<T>) => {
if (this.status !== 'pending') return;
this.fulfilledValue = result;
this.status = 'fulfilled';
this.onFulfilledCbList.forEach((cb) => cb());
};
private reject: Reject = (reason?: any) => {
if (this.status !== 'pending') return;
this.rejectionReason = reason;
this.status = 'rejected';
this.onRejectedCbList.forEach((cb) => cb());
};
then: Then<T> = (onFulfilled?: (result?: T) => any, onRejected?: (result?: T) => any) => {
const promise2 = new MyPromise<T>((resolve, reject) => {
let hasOnFulfilled = typeof onFulfilled === 'function';
let hasOnRejected = typeof onRejected === 'function';
let isFulfilled = this.status === 'fulfilled';
let isRejected = this.status === 'rejected';
let isPending = this.status === 'pending';
if (isPending) {
// 处理待处理promise的成功回调
this.onFulfilledCbList.push(() => {
queueMicrotask(() => {
try {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue as T);
resolvePromise2(promise2, resolve, reject, x);
} else {
resolve(this.fulfilledValue as T); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
});
// 处理待处理promise的失败回调
this.onRejectedCbList.push(() => {
queueMicrotask(() => {
try {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolvePromise2(promise2, resolve, reject, x);
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
});
} else if (isFulfilled) {
// 处理已成功promise的回调
queueMicrotask(() => {
try {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue as T);
resolvePromise2(promise2, resolve, reject, x);
} else {
resolve(this.fulfilledValue as T); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
} else if (isRejected) {
// 处理已失败promise的回调
queueMicrotask(() => {
try {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolvePromise2(promise2, resolve, reject, x);
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
}
});
return promise2;
}
}
function resolvePromise2<T>(promise2: MyPromise<T>, resolve: Resolve<T>, reject: Reject, x: any): void {
if (promise2 === x) {
/**
* 防止这种情况出现
* const p2 = new MyPromise((resolve) => resolve()).then(() => p2);
*/
throw new TypeError('Chaining cycle detected for promise');
}
if (x instanceof MyPromise) {
// Promise对象
x.then((y) => resolvePromise2(promise2, resolve, reject, y), reject); // 如果内层Promise是成功状态,则继续递归
} else if (isThisType(x, 'Function') || isThisType(x, 'Object')) {
let then: any = null;
try {
then = x.then;
} catch (error) {
reject(error);
}
if (isThisType(then, 'Function')) {
// thenable对象
let called = false;
try {
then!.call(
x,
(y: any) => {
if (called) return;
called = true;
resolvePromise2(promise2, resolve, reject, y); // 如果内层Promise是成功状态,则继续递归
}, // resolvePromise
(z: any) => {
if (called) return;
called = true;
reject(z);
} // rejectPromise
);
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
} else {
// 普通值
resolve(x);
}
}
function isThisType(x: any, type: string): boolean {
return Object.prototype.toString.call(x) === `[object ${type}]`;
}
const p1 = new MyPromise(); // pending
const p2 = new MyPromise((resolve) => {
resolve();
}); // fulfilled
const p3 = new MyPromise<void>((_, reject) => {
reject();
}); // rejected
const p4 = new MyPromise<string>((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('F');
} else {
reject('R');
}
}, 1000);
}); // pending -> fulfilled or rejected
const p5 = p2
.then(() => {
return 1;
})
.then(() => {
return 2;
}); // 2
const p6 = p4.then(
(res) => {
return 'p6-' + res;
},
(res) => {
return 'p6-' + res;
}
); // 'p6-F' or 'p6-R'
new MyPromise<string>((resolve) => resolve('micro')).then((val) => {
console.log('then 回调(应在微任务阶段执行)', val);
});
console.log('同步日志(应先输出)');
const p7 = p2.then(() => new MyPromise((resolve) => resolve('inner promise'))); // inner promise
/**
* trickyThenable 演示:
* 1. 首先 resolve 一个“仍在等待的 thenable”(里面用 setTimeout 异步再 resolve 真值)
* 2. 紧接着同步调用 reject
*
* - 启用 called:同步 reject 被忽略,等异步 resolve 后输出「最终结果: 最终成功」
* - 注释 called:promise 仍处于 pending,因此同步 reject 会生效,输出「最终结果: 后来又失败」
*
* 为什么myPromise不需要做这种限制?
* 因为对于Thenable对象,resolve或者reject的调用是由用户自己决定的,而myPromise中,是由myPromise类中的resolvePromise2决定的
*/
const pendingThenable: Thenable<string> = {
then(innerResolve) {
if (!innerResolve) return;
setTimeout(() => innerResolve('成功'), 0);
},
};
const trickyThenable: Thenable<string> = {
then(resolve: any, reject: any) {
// 先resolve了这个Thenable对象
resolve(pendingThenable as any);
// 后reject了这个Thenable对象(根据规范,应该忽略reject的调用)
reject('失败');
},
};
new MyPromise((resolve) => resolve('占位值'))
.then(() => trickyThenable)
.then(
(res) => console.log('最终结果:', res),
(err) => console.error('最终结果:', err)
);
setTimeout(() => {
console.log(p1, p2, p3, p4, p5, p6, p7);
}, 1000);
export {};
6.优化类型

// 6. 优化类型
type Status = 'pending' | 'fulfilled' | 'rejected';
type Executor<T> = (resolve: Resolve<T>, reject: Reject) => void;
type Resolve<T> = (result?: T | Thenable<T>) => void;
type Reject = (reason?: any) => void;
type Thenable<T> = {
then<TResult1 = T, TResult2 = never>(
onFulfilled?: ((result: T) => TResult1 | Thenable<TResult1>) | undefined | null,
onRejected?: ((reason: any) => TResult2 | Thenable<TResult2>) | undefined | null
): any;
};
class MyPromise<T> {
status: Status = 'pending';
private fulfilledValue?: T | Thenable<T>;
private rejectionReason?: any;
private onFulfilledCbList: ((result?: T) => any)[] = [];
private onRejectedCbList: ((reason?: any) => any)[] = [];
constructor(executor?: Executor<T>) {
try {
executor?.(this.resolve, this.reject);
} catch (error) {
this.reject(error as any);
}
}
private resolve: Resolve<T> = (result?: T | Thenable<T>) => {
if (this.status !== 'pending') return;
this.fulfilledValue = result;
this.status = 'fulfilled';
this.onFulfilledCbList.forEach((cb) => cb());
};
private reject: Reject = (reason?: any) => {
if (this.status !== 'pending') return;
this.rejectionReason = reason;
this.status = 'rejected';
this.onRejectedCbList.forEach((cb) => cb());
};
then<TResult1 = T, TResult2 = never>(
onFulfilled?: ((result: T) => TResult1 | Thenable<TResult1>) | undefined | null,
onRejected?: ((result: any) => TResult2 | Thenable<TResult2>) | undefined | null
): MyPromise<TResult1 | TResult2> {
const promise2 = new MyPromise<TResult1 | TResult2>((resolve, reject) => {
let hasOnFulfilled = typeof onFulfilled === 'function';
let hasOnRejected = typeof onRejected === 'function';
let isFulfilled = this.status === 'fulfilled';
let isRejected = this.status === 'rejected';
let isPending = this.status === 'pending';
if (isPending) {
// 处理待处理promise的成功回调
this.onFulfilledCbList.push(() => {
queueMicrotask(() => {
try {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue as T);
resolvePromise2(promise2, resolve, reject, x);
} else {
resolve(this.fulfilledValue as TResult1 | TResult2 | Thenable<TResult1 | TResult2> | undefined); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
});
// 处理待处理promise的失败回调
this.onRejectedCbList.push(() => {
queueMicrotask(() => {
try {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolvePromise2(promise2, resolve, reject, x);
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
});
} else if (isFulfilled) {
// 处理已成功promise的回调
queueMicrotask(() => {
try {
if (hasOnFulfilled) {
const x = onFulfilled!(this.fulfilledValue as T);
resolvePromise2(promise2, resolve, reject, x);
} else {
resolve(this.fulfilledValue as TResult1 | TResult2 | Thenable<TResult1 | TResult2> | undefined); // 如果onFulfilled不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
} else if (isRejected) {
// 处理已失败promise的回调
queueMicrotask(() => {
try {
if (hasOnRejected) {
const x = onRejected!(this.rejectionReason);
resolvePromise2(promise2, resolve, reject, x);
} else {
reject(this.rejectionReason); // 如果onRejected不是函数,则使用promise2传递调用then的promise
}
} catch (error) {
reject(error);
}
});
}
});
return promise2;
}
}
function resolvePromise2<T>(promise2: MyPromise<T>, resolve: Resolve<T>, reject: Reject, x: any): void {
if (promise2 === x) {
/**
* 防止这种情况出现
* const p2 = new MyPromise((resolve) => resolve()).then(() => p2);
*/
throw new TypeError('Chaining cycle detected for promise');
}
if (x instanceof MyPromise) {
// Promise对象
x.then((y) => resolvePromise2(promise2, resolve, reject, y), reject); // 如果内层Promise是成功状态,则继续递归
} else if (isThisType(x, 'Function') || isThisType(x, 'Object')) {
let then: any = null;
try {
then = x.then;
} catch (error) {
reject(error);
}
if (isThisType(then, 'Function')) {
// thenable对象
let called = false;
try {
then!.call(
x,
(y: any) => {
if (called) return;
called = true;
resolvePromise2(promise2, resolve, reject, y); // 如果内层Promise是成功状态,则继续递归
}, // resolvePromise
(z: any) => {
if (called) return;
called = true;
reject(z);
} // rejectPromise
);
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
} else {
// 普通值
resolve(x);
}
}
function isThisType(x: any, type: string): boolean {
return Object.prototype.toString.call(x) === `[object ${type}]`;
}
const p1 = new MyPromise(); // pending
const p2 = new MyPromise((resolve) => {
resolve();
}); // fulfilled
const p3 = new MyPromise<void>((_, reject) => {
reject();
}); // rejected
const p4 = new MyPromise<string>((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('F');
} else {
reject('R');
}
}, 1000);
}); // pending -> fulfilled or rejected
const p5 = p2
.then(() => {
return 1;
})
.then(() => {
return 2;
}); // 2
const p6 = p4.then(
(res) => {
return 'p6-' + res;
},
(res) => {
return 'p6-' + res;
}
); // 'p6-F' or 'p6-R'
new MyPromise<string>((resolve) => resolve('micro')).then((val) => {
console.log('then 回调(应在微任务阶段执行)', val);
});
console.log('同步日志(应先输出)');
const p7 = p2.then(() => new MyPromise((resolve) => resolve('inner promise'))); // inner promise
/**
* trickyThenable 演示:
* 1. 首先 resolve 一个“仍在等待的 thenable”(里面用 setTimeout 异步再 resolve 真值)
* 2. 紧接着同步调用 reject
*
* - 启用 called:同步 reject 被忽略,等异步 resolve 后输出「最终结果: 最终成功」
* - 注释 called:promise 仍处于 pending,因此同步 reject 会生效,输出「最终结果: 后来又失败」
*
* 为什么myPromise不需要做这种限制?
* 因为对于Thenable对象,resolve或者reject的调用是由用户自己决定的,而myPromise中,是由myPromise类中的resolvePromise2决定的
*/
const pendingThenable: Thenable<string> = {
then(innerResolve) {
if (!innerResolve) return;
setTimeout(() => innerResolve('成功'), 0);
},
};
const trickyThenable: Thenable<string> = {
then(resolve: any, reject: any) {
// 先resolve了这个Thenable对象
resolve(pendingThenable as any);
// 后reject了这个Thenable对象(根据规范,应该忽略reject的调用)
reject('失败');
},
};
new MyPromise((resolve) => resolve('占位值'))
.then(() => trickyThenable)
.then(
(res) => console.log('最终结果:', res),
(err) => console.error('最终结果:', err)
);
setTimeout(() => {
console.log(p1, p2, p3, p4, p5, p6, p7);
}, 1000);
export {};
测试
-
将编译之后的js代码放在index.js中
// index.js "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var MyPromise = /** @class */ (function () { // ... }()); function resolvePromise2(promise2, resolve, reject, x) { // ... } function isThisType(x, type) { // ... } -
添加
deferred静态方法// index.js "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var MyPromise = /** @class */ (function () { // ... }()); function resolvePromise2(promise2, resolve, reject, x) { // ... } function isThisType(x, type) { // ... } MyPromise.deferred = function() { let result = {}; result.promise = new MyPromise((resolve, reject) => { result.resolve = resolve; result.reject = reject; }); return result; } module.exports = MyPromise; -
修改
package.json{ "dependencies": { "promises-aplus-tests": "^2.1.2" }, "scripts": { "test": "promises-aplus-tests index" } } -
执行命令
pnpm test
"Knowledge isn't free. You have to pay attention."

浙公网安备 33010602011771号