关于javascript:手写Promise18promise实现完整代码

43次阅读

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

残缺代码如下:

// 定义三个状态
const PENDING = 'pending'; // 期待
const FULFILLED = 'fulfilled'; // 胜利
const REJECTED = 'rejected'; // 失败

class MyPromise {constructor(executor) {
        try {executor(this.resolve, this.reject);
        } catch (e) {this.reject(e)
        }
    }
    // 定义一个示意状态的属性
    status = PENDING;
    // 定义两个实例属性,示意胜利之后的值和失败后的起因
    value = undefined;
    reason = undefined;
    // 胜利回调
    successCallback = [];
    // 失败回调
    failedCallback = [];

    // 两个属性, 这里定义成箭头函数,是因为咱们在应用的时候是间接调用,// 而一般函数外部 this 的指向 window 或者是 undefined,定义成箭头函数使函数外部 this 指向指向类实例对象
    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()();}
    }
    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()();}
    }

    then(successCallback, failedCallback) {
        // 可选参数
        successCallback = successCallback ? successCallback : value => value;
        failedCallback = failedCallback ? failedCallback : reason => {throw reason};
        let promise2 = new Promise((resolve, reject) => {
            // 状态判断
            if (this.status === FULFILLED) {setTimeout(() => {
                    try {
                        // 定义胜利回调返回值,传给下一个 then 的胜利回调
                        let successRtn = successCallback(this.value);
                        // 判断 x 的值是一般值还是 promise 对象
                        // 如果是一般值 间接调用 resolve 
                        // 如果是 promise 对象 查看 promsie 对象返回的后果 
                        // 再依据 promise 对象返回的后果 决定调用 resolve 还是调用 reject
                        // 执行 resolve 办法,相当于把返回值传递给下一个 then 的胜利回调函数
                        resolvePromise(promise2, successRtn, resolve, reject);
                    } catch (e) {reject(e);
                    }
                }, 0);
            } else if (this.status === REJECTED) {setTimeout(() => {
                    try {let failedRtn = failedCallback(this.reason);
                        resolvePromise(promise2, failedRtn, resolve, reject);
                    } catch (e) {reject(e)
                    }
                }, 0);
            } else {
                // 期待,须要将胜利回调和失败回调存储起来,期待须要执行的时候才执行
                this.successCallback.push(() => {setTimeout(() => {
                        try {let successRtn = successCallback(this.value);
                            resolvePromise(promise2, successRtn, resolve, reject);
                        } catch (e) {reject(e);
                        }
                    }, 0);
                });
                this.failedCallback.push(() => {setTimeout(() => {
                        try {let failedRtn = failedCallback(this.reason);
                            resolvePromise(promise2, failedRtn, resolve, reject);
                        } catch (e) {reject(e)
                        }
                    }, 0);
                });
            }
        });
        return promise2;
    };

    catch (failCallback) {this.then(undefined, failCallback)
    };

    finally(callback) {
        return this.then(value => {return MyPromise.resolve(callback()).then(() => value);
        }, reason => {return MyPromise.resolve(callback()).then(() => {throw reason})
        })
    };

    static all(array) {let result = [];
        // 用于判断以后执行值是否等于数组长度,相等时才执行 resolve()let idx = 0;

        return new MyPromise((resolve, reject) => {
            // 增加元素办法
            function addElement(index, value) {result[index] = value;
                idx++;
                if (idx === array.length) {resolve(result)
                }
            }
            for (let i = 0; i < array.length; ++i) {let cur = array[i];
                // 判断 cur 是否是一般值,一般值间接进入 result 数组,// promise 对象就执行它, 调用 then 办法,执行胜利则增加到 result 数组,如果失败
                if (cur instanceof MyPromise) {
                    // promise 对象
                    cur.then(value => addElement(i, value), reason => reject(reason))
                } else {
                    // 一般值
                    addElement(i, array[i]);
                }
            }
        })
    }

    static race(array) {return new MyPromise((resolve, reject) => {for (let i = 0; i < array.length; ++i) {let cur = array[i];
                if (cur instanceof MyPromise) {cur.then(resolve, reject);
                } else {resolve(cur)
                }
            }
        })
    }

    static resolve(e) {if (e instanceof MyPromise) {return e;} else {return new MyPromise(resolve => resolve(e))
        }
    }
}

function resolvePromise(promise2, e, resolve, reject) {if (promise2 === e) {return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
    }
    if (e instanceof MyPromise) {
        // promise 对象
        // e.then((value) => {//     resolve(value)
        // }, (reason) => {//     reject(reason)
        // })
        // 简化代码
        e.then(resolve, reject);
    } else {
        // 一般值
        resolve(e);
    }
}

module.exports = MyPromise;

正文完
 0