关于javascript:手写Promise13promise中then方法的多次调用

39次阅读

共计 1590 个字符,预计需要花费 4 分钟才能阅读完成。

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 办法中,对 successCallbackfailedCallback只是简略的赋值。这里须要做一个更改,他们的类型须要更改为数组,不便前面存储,在 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,测试胜利。

正文完
 0