手寫Promise,1.7promise中all(),race(),resolve(),cath(),finally()的實現

Promise.all()
Promise.all()方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。
Promise.all()方法接受一個數組做爲參數,數組中若是有不是promise實例的狀況,就會先調用下面講到的Promise.resolve方法,將參數轉爲 Promise 實例,再進一步處理。Promise.all()方法的參數能夠不是數組,但必須具備 Iterator 接口,且返回的每一個成員都是 Promise 實例。
Promise.all()返回值也是一個promise對象,當全部狀態都變成fulfilled,返回值的狀態纔會變成fulfilled,當有一個promise實例的狀態變成rejected,此時第一個被reject的實例的返回值,會傳遞給返回值的回調函數。數組

實現過程當中定義一個執行結果的數組,遍歷all()參數,若是是普通值,直接進入結果數組,若是是promise實例,就先執行,由於for循環有當即執行的特色,而咱們的promise實例有可能會有異步代碼,向下傳遞執行結果的時候必需要保證咱們全部的實例執行完。傳遞結果以前要判斷全部實例代碼是否執行完。promise

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]);
                }
            }
        })
    }

promise.race()
race()方法相似,更加簡單,遍歷傳入參數(數組對象),若是是普通值就調用resolve()回調,若是是promise實例,執行then方法異步

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)
                }
            }
        })
    }

promise.resolve()
將現有對象轉換爲pomise對象,它的返回值就是一個promise對象。方便後面調用then方法。實現它只須要稍做判斷便可函數

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

Promise.prototype.finally()
finally()方法用於指定無論 Promise 對象最後狀態如何,都會執行的操做。該方法是 ES2018 引入標準的。finally方法的回調函數不接受任何參數,不依賴於 Promise 的執行結果。函數體內執行then方法會返回一個promise對象,成功回調或者失敗回調執行callback便可,而且返回成功回調結果或者拋出失敗異常,可是考慮到有異步代碼的狀況,藉助resolve()方法,在resolve方法中把callback調用的結果傳遞出去,不管是普通值仍是promise都轉成promise對象。以後就能夠執行then方法。this

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

Promise.prototype.catch()
Promise.prototype.catch()方法是.then(null, rejection).then(undefined, rejection)的別名,用於指定發生錯誤時的回調函數。then()方法指定的回調函數,若是運行中拋出錯誤,也會被catch()方法捕獲。
Promise 對象的錯誤具備「冒泡」性質,會一直向後傳遞,直到被捕獲爲止。也就是說,錯誤老是會被下一個catch語句捕獲。
跟傳統的try/catch代碼塊不一樣的是,若是沒有使用catch()方法指定錯誤處理的回調函數,Promise 對象拋出的錯誤不會傳遞到外層代碼,即不會有任何反應。
在catch方法中執行then方法,第一次參數傳入null或者undefined。第二個參數就是failCallbackprototype

catch (failCallback) {
        this.then(undefined, failCallback)
    }
相關文章
相關標籤/搜索