首先,需要定义一个名为 MyPromise 的构造函数,它接受一个执行器函数作为参数;该执行器函数接收两个参数:resolve 和 reject,用于改变 Promise 状态的内部函数:
class MyPromise {
constructor(executor) {
this.state = 'pending'; // 初始化状态为pending
this.value = undefined; // fulfilled时保存的值
this.reason = undefined; // rejected时保存的原因
this.onFulfilledCallbacks = []; // fulfilled时执行的回调队列
this.onRejectedCallbacks = []; // rejected时执行的回调队列
// 执行器函数会在new Promise时立即执行
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
// 如果执行器函数抛出错误,则直接将Promise变为rejected状态
this.reject(error);
}
}
resolve(value) {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
// 将pending状态下的成功回调全部执行
this.onFulfilledCallbacks.forEach(cb => cb(this.value));
}
}
reject(reason) {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
// 将pending状态下的失败回调全部执行
this.onRejectedCallbacks.forEach(cb => cb(this.reason));
}
}
// then方法用于注册成功和失败的回调
then(onFulfilled, onRejected) {
const self = this;
let resolvedPromise;
// 根据规范,onFulfilled/onRejected都是可选参数,并且需确保为函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val;
onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err; };
// 返回一个新的Promise以便进行链式调用
resolvedPromise = new MyPromise((resolve, reject) => {
if (self.state === 'pending') {
// 如果当前Promise未决,则将回调存入相应的队列
self.onFulfilledCallbacks.push(() => {
try {
const x = onFulfilled(self.value);
resolvePromise(resolvedPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
});
self.onRejectedCallbacks.push(() => {
try {
const x = onRejected(self.reason);
resolvePromise(resolvedPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
});
} else if (self.state === 'fulfilled') {
// 当前Promise已决议(resolved),则立即执行onFulfilled回调
setTimeout(() => {
try {
const x = onFulfilled(self.value);
resolvePromise(resolvedPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (self.state === 'rejected') {
// 当前Promise已拒绝(rejected),则立即执行onRejected回调
setTimeout(() => {
try {
const x = onRejected(self.reason);
resolvePromise(resolvedPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
});
return resolvedPromise;
}
// 这里省略了catch、finally等方法以及Promise.all、race等静态方法的实现
}
// 辅助函数,处理then中返回值的逻辑
function resolvePromise(promise2, x, resolve, reject) {
// 规范要求对x进行递归解析,并处理循环引用等情况
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
}
let called; // 避免重复调用resolve或reject
if (x instanceof MyPromise) {
if (x.state === 'pending') {
x.then(
value => resolvePromise(promise2, value, resolve, reject),
reason => reject(reason)
);
} else {
x.then(resolve, reject);
}
} else if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
try {
let then = x.then;
if (typeof then === 'function') {
// 处理thenable对象
then.call(
x,
y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
},
r => {
if (called) return;
called = true;
reject(r);
}
);
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x); // 基本类型的值直接resolve
}
}