Promise源碼實現class版

class封裝完整版
(function(window){
    // 進行中狀態
    const _PENDING = "pending";
    // 已成功狀態
    const _RESOLVED = "resolved";
    // 已失敗狀態
    const _REJECTED = "rejected";
    class MyPromise {
        constructor(executor) {
            // 設置狀態初始值爲 pending
            this.status = _PENDING;
            // 設置初始值爲 undefined
            this.value = undefined;
            // 添加回調函數隊列
            this.onCallBacks = [];

            // 成功時執行
            function _resolve(value) {
                if (this.status !== "pending")
                    return;

                // 修改 MyPromise 對象的狀態爲 resolve
                this.status = _RESOLVED;
                // 保存成功的數據
                this.value = value;
                //檢查回調數組中是否存在數據
                if (this.onCallBacks.length > 0) {
                    // 異步執行
                    setTimeout(() => {
                        this.onCallBacks.forEach(onCb => {
                            onCb.onResolved.call(this);
                        });
                    });
                }
            }

            // 失敗時執行
            function _reject(reason) {
                if (this.status !== "pending")
                    return;
                // 修改 MyPromise 對象的狀態爲 resolve
                this.status = _REJECTED;
                // 保存失敗的數據
                this.value = reason;
                //檢查回調數組中是否存在數據
                if (this.onCallBacks.length > 0) {
                    // 異步執行
                    setTimeout(() => {
                        this.onCallBacks.forEach(onCb => {
                            onCb.onRejected.call(this);
                        });
                    });
                }
            }

            try {
                // 立即執行 executor
                executor(_resolve.bind(this), _reject.bind(this))
            } catch (err) {
                _reject.call(this, err);
            }
        }

        then(onResolved, onRejected) {
            return new MyPromise((resolve, reject) => {
                /*
                * 參數 cb 的值爲 onResolved 或 onRejected 函數
                *  */
                function _callback(cb) {
                    // 增加try方法,如果出現異常,執行reject
                    try {
                        let result = cb(this.value);
                        // 判斷返回結果是否爲MyPromise類型
                        if (result instanceof MyPromise) {
                            // result 是 MyPromise,下面這行代碼是上方代碼的簡寫形式
                            result.then(resolve, reject);
                        } else {
                            // 非MyPromise類型,將結果直接傳遞過去
                            resolve(result);
                        }
                    } catch (err) {
                        // 出現異常,執行reject
                        reject(err);
                    }
                }

                // 防止使用者不傳成功或失敗回調函數,所以成功失敗回調都給了默認回調函數
                onResolved = typeof onResolved === "function" ? onResolved : value => value;
                onRejected = typeof onRejected === "function" ? onRejected : error => {
                    throw error
                };
                switch (this.status) {
                    // 當狀態爲resolve時,執行onResolved,並傳遞結果
                    case _RESOLVED:
                        // 通過 setTimeout 讓代碼異步執行
                        setTimeout(() => {
                            _callback.call(this, onResolved);
                        });
                        break;
                    // 當狀態爲reject時,執行onRejected,並傳遞結果
                    case _REJECTED:
                        // 通過 setTimeout 讓代碼異步執行
                        setTimeout(() => {
                            _callback.call(this, onRejected);
                        });
                        break;
                    // 當狀態爲 pending 時,將要執行的回調函數放置到隊列中,待狀態更改完畢後再調用。
                    case _PENDING:
                        this.onCallBacks.push({
                            onResolved() {
                                //獲取回調函數的執行結果
                                _callback.call(this, onResolved);
                            },
                            onRejected() {
                                _callback.call(this, onRejected);
                            }
                        });
                        break;
                }
            })
        }

        catch = function (onRejected) {
            return this.then(undefined, onRejected);
        }
        // 函數對象 resolve 的封裝
        static resolve(value) {
            return new MyPromise((resolve, reject) => {
                if (value instanceof MyPromise) {
                    value.then(resolve, reject);
                } else {
                    resolve(value);
                }
            });
        }
        // 函數對象 reject 的封裝
        static reject(reason) {
            return new MyPromise((resolve, reject) => {
                reject(reason);
            })
        }
        //函數對象 all 的封裝
        static all(MyPromises) {
            return new MyPromise((resolve, reject) => {
                let pValues = [];
                let flag = 0;
                for (let i = 0; i < MyPromises.length; i++) {
                    MyPromises[i].then(v => {
                        pValues[i] = v;
                        flag++;
                        if (flag >= MyPromises.length) {
                            resolve(pValues);
                        }
                    }, r => {
                        reject(r);
                    })
                }
            });
        }
        //函數對象 race
        static race(MyPromises) {
            return new MyPromise((resolve, reject) => {
                for (let i = 0; i < MyPromises.length; i++) {
                    MyPromises[i].then(value => {
                        resolve(value);
                    }, reason => {
                        reject(reason);
                    })
                }
            });
        }
    }
    window.MyPromise = MyPromise;
})(window)

—————END—————
喜歡本文的朋友們,歡迎關注公衆號 張培躍,收看更多精彩內容!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章