#借鉴袁老师的思路
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
class MyPromise {
constructor(fn) {
this.state = PENDING;
this.value = void 0;
this.handlers = [];
try {
fn(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
changeState(newState, value) {
if (this.state !== PENDING) {
return;
}
this.state = newState;
this.value = value;
// 运行回调函数
this.runHandlers();
}
resolve(value) {
this.changeState(RESOLVED, value);
}
reject(value) {
this.changeState(REJECTED, value);
}
pushHandlers(fn, state, resolve, reject) {
this.handlers.push({
fn,
state,
resolve,
reject,
});
}
runHandlers() {
if (this.state === PENDING) {
return;
}
// 循环数组,运行每一个回调函数
while (this.handlers[0]) {
const handler = this.handlers[0];
this.runOneHandler(handler);
this.handlers.shift();
}
}
runOneHandler({ fn, state, resolve, reject }) {
// 异步执行,等待状态改变后,再运行回调函数
queueMicrotask(() => {
// 如果状态不是传入的 state,则直接返回
if (this.state !== state) {
return;
}
// 如果传入的 fn 不是函数,则根据状态,调用 resolve 或 reject 函数,传入值(状态穿透)
if (typeof fn !== "function") {
this.state === RESOLVED ? resolve(this.value) : reject(this.value);
return;
}
try {
// 调用传入的函数,传入值,改变状态
const res = fn(this.value);
resolve(res);
} catch (error) {
reject(error);
}
});
}
// then 函数,接受两个回调函数,用于改变状态
then(OnResolved, OnRejected) {
// 返回一个新的 Promise 对象,传入 resolve 和 reject 函数,用于改变状态
return new MyPromise((resolve, reject) => {
// 添加回调函数,传入 resolve 和 reject 函数,用于改变状态
this.pushHandlers(OnResolved, RESOLVED, resolve, reject);
this.pushHandlers(OnRejected, REJECTED, resolve, reject);
// 运行回调函数
this.runHandlers();
});
}
}