要分装promise先理清思绪
1. 先实现executor的立即执行
2. 实现MyPromise中有两个属性 state, result
3. 实现 executor的两个参数 resolve和reject, 传递给executor
4. resolve和reject调用的时候,能够 state状态改变, result进行保存
5. 实现then方法,onFullfilled onRejected, 如果状态是fulfilled的时候,执行onFulfilled
6. 如果调用then方法的时候,状态还是pending, onFullfilled onRejected放到数组中存起来
7. 在resolve和reject方法内部, 等到状态改变的时候,重新调用then方法,then方法的参数从第6步的数组中取出来
class MyPromise {
_state = "pending";
_result = undefined;
_onFulfilled = [];
_onRejected = [];
constructor(executor) {
if (!executor || typeof executor !== "function") {
throw new TypeError("MyPromise必须接受一个函数作为初始参数");
}
executor(this._resolve.bind(this), this._reject.bind(this));
}
// promise的resolve方法被调用,1. 状态改变 ; 2. 接受的参数作为结果进行保存
_resolve(result) {
if (this._state === "pending") {
this._state = "fulfilled";
this._result = result;
this.then(this._onFulfilled.pop(), this._onRejected.pop());
}
}
_reject(result) {
if (this._state === "pending") {
this._state = "rejected";
this._result = result;
this.then(this._onFulfilled.pop(), this._onRejected.pop());
}
}
// 1. 实现链式调用
// a. then方法的返回值 是promise对象
// b. then方法 结果和状态 是由 onFulfilled回调函数返回值来决定
then(onFulfilled, onRejected) {
// console.log(this._state)
if (this._state === "fulfilled") {
if (!onFulfilled) return;
return new MyPromise((resolve, reject) => {
// setTimeout(() => {
let result = onFulfilled(this._result);
// 判断result是否为MyPromise的实例
// 如果 result 是MyPromise的实例,then方法的返回promise对象的状态和结果 都跟result一样
if (result instanceof MyPromise) {
console.log("promise");
// 核心代码
result.then(resolve, reject);
} else {
resolve(result);
}
// });
});
} else if (this._state === "rejected") {
if (!onRejected) return;
return new MyPromise((resolve, reject) => {
let result = onRejected(this._result);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
});
// setTimeout(() => {
// });
} else if (this._state === "pending") {
// 如果 then方法执行时,发现 状态还是pending,我们就把onFulfilled和onRejected暂存起来,
// 等状态发生改变的时候,再来执行
return new MyPromise((resolve, reject) => {
this._onFulfilled.push(() => {
let result = onFulfilled && onFulfilled(this._result);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
});
this._onRejected.push(() => {
let result = onRejected && onRejected(this._result);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
});
});
}
}
}