promise
中有一个很重要的特点
同一个promise
对象下面的then
方法是可以被调用多次。
举个例子,测试代码更改如下:
const MyPromise = require('./mypromise');
let promise = new MyPromise((resolve, reject) => {
resolve('---success----');
// setTimeout(()=>{
// resolve('success')
// },3000)
// reject("---failed----");
})
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason)
})
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason)
})
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason)
})
如果是同步代码,这里没什么大问题,因为已经更改了状态,代码会向下执行,但是如果出现了异步代码,或者出现多个异步代码。此时的状态无法存储,之前的then
方法中,对successCallback
和failedCallback
只是简单的赋值。这里需要做一个更改,他们的类型需要更改为数组,方便后面存储,在resolve
方法和reject
方法中,需要判断数组长度是否为0,如果数组中还有元素,就弹出第一个并执行,知道数组长度为0。
// 成功回调
successCallback = [];
// 失败回调
failedCallback = [];
resolve = value => {
// 如果状态不是等待,阻止程序向下进行
if (this.status !== PENDING) return
// 更改状态为成功
this.status = FULFILLED
// 保存成功的值
this.value = value;
// 判断成功回调是否存在,如果存在就调用
// this.successCallback && this.successCallback(this.value);
while (this.successCallback.length) {
this.successCallback.shift()(this.value);
}
}
reject = reason => {
// 如果状态不是等待,阻止程序向下进行
if (this.status !== PENDING) return
// 更改状态为失败
this.status = REJECTED
// 保存失败的原因
this.reason = reason;
// 判断失败回调是否存在,存在就调用
// this.failedCallback && this.failedCallback(this.reason);
while (this.failedCallback.length) {
this.failedCallback.shift()(this.reason);
}
}
then
方法也需要更改
then(successCallback, failedCallback) {
// 状态判断
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJECTED) {
failedCallback(this.reason)
} else {
// 等待,需要将成功回调和失败回调存储起来,等待需要执行的时候才执行
this.successCallback.push(successCallback);
this.failedCallback.push(failedCallback);
}
}
测试代码测试,3秒后连续输出success,测试成功。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。