写在开头:如果被大佬们看到了有错误还请斧正,如果把萌新带到了沟里,你在爬出来就好了(手动滑稽)
在 Promise 核心代码实现的时候并没有做异步的逻辑处理,如果出现了异步的情况可能会有问题。接下来要实现的是关于 Promise 异步逻辑。
这是上次实现的 myPromise
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'reiected';
class myPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
status = PENDING;
value = undefined;
reason = undefined;
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
};
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
};
then(successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
}
};
}
在这里调用自定义的 myPromise 并且加入一段异步代码
let promise = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
// reject('失败');
}, 3000);
});
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason);
});
接下来分析一下这段代码的执行结果是啥样婶儿的:
- 代码是按顺序从上到下执行的在创建了一个自定义的 Promise 之后,它里面的回调函数会立即执行。
- 在立即执行的回调函数中遇到了 setTimeout,也就是遇到了异步代码,延时三秒后执行里面的逻辑。
- promise.then 中的回调是属于立即执行的,此时 then 方法执行,判断当前状态,然而 status 的状态是 pending,then 方法没有对于 pending 的判断,于是它懵逼了
综上分析,是缺了关于 pending 的判断
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'reiected';
class myPromise {
***
then(successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
} else {
// 添加 pending 状态的判断
// then 方法要改变状态,但是是要改为成功状态还是要改为失败状态,then 方法又一次懵逼
}
};
}
回看调用的 myPromise 发现里面有三秒后执行成功的操作,也就是说三秒后再进行判断就能知道调用的是成功回调还是失败回调了,那 pending 需要做的操作就是把这个状态存储起来。
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'reiected';
class myPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
status = PENDING;
value = undefined;
reason = undefined;
// 成功回调
successCallback = undefined;
// 失败回调
failCallback = undefined;
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
// 判断成功回调是否存在,如果存在就调用成功回调
this.successCallback && this.successCallback(this.value);
};
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
// 判断失败回调是否存在,如果存在就调用失败回调
this.failCallback && this.failCallback(this.reason);
};
then(successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
} else {
// 存储成功/失败回调
this.successCallback = successCallback;
this.failCallback = failCallback;
}
};
}
这样一来关于异步代码的实现就完事儿了。
接下来实现 then 方法多次调用和链式调用