實現Promise的詳細流程(實現一個最完整的Promise構造函數)

1、建立promise構造函數基本架構

  • 獲取狀態

    status = 'pending' 初始化 'resolved' 已獲取數組

    'rejected' 獲取失敗promise

  • 初始數據

    data = undefined架構

  • 定義成功/失敗回調函數容器

    onResolved = undefined onRejected = undefined異步

  • 定義成功/失敗函數 resolve/reject 內部函數

    _this.status更改狀態爲已獲取/獲取失敗 _this.data保存成功/失敗數據this

    • 若是成功/失敗回調函數已定義 當即異步執行成功/失敗回調
  • 執行器執行成功/失敗函數 resolve/rejectprototype

    • 如捕獲到異常則表明then retrun promise的結果爲失敗

      執行reject, 傳入錯誤code

2、定義構造函數原型then函數, 接收成功/失敗回調 onResolved/onRejected, 最終then返回一個新的promise實例

  • 定義return promise結構, 接收成功/失敗函數參數, return promise的執行結果由onResolved, onRejected決定orm

    1. return promise定義DealWithThenReturnPromise(return promise狀態處理函數)並接受then的成功/失敗回調 ====>onResolved, onRejected 有三種結果狀況來改變return pormise的狀態原型

      執行結果是異常拋出, 執行return promise的失敗函數, 並傳入異常數據

      執行結果是promise實例, 執行return promise是否調用成功/失敗函數, 由執行結果的promise的結果決定

      執行結果不是promise實例, 執行return promise的成功函數, 並傳入執行結果

      執行then傳入的成功/失敗回調, 並將返回值保存爲result

      1. result爲Promise的實例

        執行result實例then方法, 並在其成功/失敗回調傳入return promise的成功/失敗函數

      2. result不是promise實例 執行return promise成功函數,傳入result
      3. result執行結果是異常拋出 捕獲異常並執行return promise失敗函數, 傳入error
  • return promise定義三種數據獲取狀態處理方式

    ====>數據獲取有三種狀況會發生, 而且每一種狀態都得是異步執行 數據已經獲取成功, 表明能夠直接執行並獲取到onResolved返回值 數據獲取失敗, 表明能夠直接執行並獲取到onRejected返回值 數據並無獲取, 表明onRejected,onResolved並不能立刻執行, 要存入實例當中由執行器的回調函數執行

    1. 數據獲取成功 執行return promise狀態處理函數, 並傳入成功回調函數
    2. 數據獲取失敗 執行return promise狀態處理函數, 並傳入失敗回調函數
    3. 數據暫未獲取 封裝成功/失敗函數, 在封裝函數內執行return promise狀態處理函數, 並傳入then成功/失敗回調 這個封裝函數最終由當前promise實例的成功/回調函數執行 並最終會由return promise狀態處理函數處理數據

3、定義Promise.resolve

Promise.resolve接收三類參數, 並返回一個新的promise實例 成功的Promise實例 失敗的Promise實例 不是Promise實例的任意值

Promise.resolve return promise架構 判斷傳參是否是Promise實例, 若是是, 調用then方法, 並綁定return promise的成功/失敗函數 參數不是Promise, 直接調用return Promise成功函數, 並傳入參數

4、定義Promise.all

Promise.all接收一個Promise或其餘值數組 若是所有成功, 則執行return promise並傳入Promise成功的結果, 只要有一個失敗, 則執行失敗的return Promise 傳入失敗值

Promise.all return promise架構 定義一個數組容器 定義一個計數器 遍歷數組(forEach), 每次進入循環計數器+1 執行每一個promise實例then,若是成功,在將值根據下標存入數組容器 判斷promise數組length是否等於計數器,若是等於,表明須要執行return promise的成功函數 若是then執行的是失敗,則直接調用return promise 失敗函數,並傳入then失敗值

5、定義promise.rule

Promise.rule接收一個Promise或其餘值數組 若是一個成功/失敗,則直接調用return promise 成功/失敗函數

實現具體代碼

//! 定義經常使用常量
//? 未獲取, 表明當前promise的resolve是異步完成的
const PENDING = 'pending'
//? 已獲取, 表明當前promise是同步執行的
const RESOLVED = 'resolved'
//? 失敗, 表明當前promise的執行結果爲失敗
const REJECTED = 'rejected'
//! 三種狀態只能從pending中更改一次

function Promise(executor) {
    const _this = this
    //! Promise構造函數定義初始化狀態爲 未獲取狀態
    _this.status = PENDING
    //! Promise構造函數定義初始化數據爲undefined
    _this.data = undefined
    //! Promise構造函數定義初始化成功容器爲undefined
    _this.onResolved = undefined
    //! Promise構造函數定義初始化失敗容器爲undefined
    _this.onRejected = undefined
    //! 獲取成功函數
    function resolve(value) {
        //! 若是狀態不是pending, 則直接返回
        if (_this.status !== PENDING) { return }
        //! 將狀態更改成獲取成功
        _this.status = RESOLVED
        //! 將數據保存
        _this.data = value
        //! 若是成功函數已經定義, 表明須要異步執行成功回調 onResolved 並傳入數據
        if (_this.onResolved) {
            setTimeout(() => _this.onResolved(value));
        }
    }
    //! 獲取失敗函數
    function reject(reason) {
        //! 若是狀態不是pending, 則直接返回
        if (_this.status !== PENDING) { return }
        //! 將狀態更改成獲取失敗
        _this.status = REJECTED
        //! 將數據保存
        _this.data = reason
        //! 若是失敗函數已經定義, 表明須要異步執行失敗回調 onResolved 並傳入數據
        if (_this.onRejected) {
            setTimeout(() => _this.onRejected(reason));
        }
    }
    try {
        executor(resolve, reject)
    } catch (error) {
        //! 若是捕獲到錯誤 則表明then retrun promise的結果爲失敗
        //! 那麼直接調用retrun promise的失敗函數, 向下傳遞失敗
        reject(error)
    }
}
Promise.prototype = {
    then: function (onResolved, onRejected) {
        //! onResolved 成功回調; onRejected 失敗回調;
        const _this = this
        //! 當執行then, 返回一個新的promise
        //! return promise的執行結果由onResolved, onRejected決定
        return new Promise((resolve, reject) => {
            /* 
            !   ----->數據獲取有三種狀況會發生
            !   數據已經獲取成功, 表明能夠直接執行並獲取到onResolved返回值
            !   數據獲取失敗, 表明能夠直接執行並獲取到onRejected返回值
            !   數據並無獲取, 表明onRejected,onResolved並不能立刻執行, 要存入實例當中由執行器的回調函數執行
            !   ----->而且每一種狀態都得是異步執行
            */
            if (_this.status === RESOLVED) {
                //! 數據獲取成功, 執行return promise狀態處理函數, 並傳入成功回調
                setTimeout(() => DealWithThenReturnPromise(onResolved));
            } else if (this.status === REJECTED) {
                //! 數據獲取失敗, 執行return promise狀態處理函數, 並傳入失敗回調
                setTimeout(() => DealWithThenReturnPromise(onRejected));
            } else {
                //! 數據暫未獲取, 封裝成功/失敗函數, 在封裝函數內執行return promise狀態處理函數, 並傳入then成功/失敗回調,
                //! 這個封裝函數最終由當前promise實例的成功/回調函數執行
                //! 當獲取數據的時候, 會在DealWithThenReturnPromise函數中獲取
                _this.onResolved = value => DealWithThenReturnPromise(onResolved)
                _this.onRejected = reason => DealWithThenReturnPromise(onRejected)
            }
            //! 定義處理return promise 函數, 傳入要處理的成功|失敗函數
            function DealWithThenReturnPromise(callback) {
                /* 
                !   onResolved, onRejected 有三種結果狀況來改變return pormise的狀態
                !   執行結果是異常拋出, 執行return promise的失敗函數, 並傳入異常數據
                !   執行結果是promise實例, 執行return promise是否調用成功/失敗函數, 由執行結果的promise的結果決定
                !   執行結果不是promise實例, 執行return promise的成功函數, 並傳入執行結果
                */
                try {
                    //! 將then成功/失敗返回值保存
                    const result = callback(_this.data)
                    if (result instanceof Promise) {
                        //! 執行結果是promise實例, 由執行結果promise實例決定return promise的執行結果
                        //! 易懂寫法 result.then(value=> resolve(value), reason=> reject(reason))

                        //! 簡便寫法
                        result.then(resolve, reject)
                        //! 這裏將return promise的成功/失敗回調傳入執行結果實例then中, 因此這裏的resolve有雙層意義, 
                        //! 一是結果實例then的onResolved與onRejected, 
                        //! 二是return promise的resolve與reject
                    } else {
                        //! 執行結果不是promise實例, 執行return promise成功函數, 傳入執行結果
                        resolve(result)
                    }
                } catch (error) {
                    //! 執行結果是異常拋出, 捕獲異常並執行 return promise 失敗函數, 傳入異常
                    reject(error)
                }
            }

        })
    },
    catch: function (reject) { return this.then(null, reject) },
}
Promise.resolve = function (value) {
    /* 
    ! Promise.resolve接收有三種參數
    ! 1.實例結果是失敗的
    ! 2.實例結果是成功的
    ! 3.不是實例
    */
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            //! 若是value是Promise的實例
            value.then(resolve, reject)
        } else {
            //! 若是不是
            resolve(value)
        }
    })

}
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason)
    })
}
Promise.all = function (promises) {
    //! 建立一個計數器
    let resolveCount = 0
    //! 建立數組指定長度
    const values = new Array(promises.length)
    return new Promise((resolve, reject) => {
        promises.forEach((item, index) => {
            Promise.resolve(item).then(
                value => {
                    //! 當獲取成功時, 計數器+1
                    resolveCount++
                    //! promise實例成功, 將結果保存在數組
                    values[index] = value
                    //! 當執行到最後一個, 執行all return promise成功函數, 傳入成功值的數組
                    promises.length === resolveCount ? resolve(values) : []
                },
                //! 只要有一個失敗, 那麼就all返回的promise就是失敗
                reason => reject(reason)
            )
        })
    })
}
Promise.rule = function (promises) {
    return new Promise((resolve, reject) => {
        promises.forEach(item => {
            Promise.resolve(item).then(resolve, reject)
        })
    })
}
相關文章
相關標籤/搜索