promise源碼深度解析

//promise的封裝
        class myPromise {
            constructor(fn) {
                if (typeof fn !== 'function') { //判斷傳輸的類型不是函數 報相應的錯誤
                    throw TypeError(`myPromise resolver ${fn} is not a function`)
                }
                this.status = 'pending'; //設置默認狀態
                this.data = undefined; //設置默認值
                this.resolveCBArr = []; // 設置存儲成功的回調函數
                this.rejectCBArr = []; // 設置存儲失敗的回調函數
                // 函數內部的resolve函數
                let resolve = (data) => { //成功的回調
                    if (this.status == 'pending') {
                        this.status = 'resolved'
                        this.data = data;
                        this.resolveCBArr.forEach(fn => fn()); //遍歷resolveArr數組每一位 而後依次執行
                    }
                }
                // 函數內部的reject函數
                let reject = (data) => { //失敗的回調
                    if (this.status == 'pending') {
                        this.status = 'rejected'
                        this.data = data;
                        this.rejectCBArr.forEach(fn => fn()); //遍歷rejectArr數組每一位 而後依次執行
                    }
                }
                fn(resolve, reject) //掛載到new myPromise((resolve,reject) => {})
            }
            //原型then方法的封裝
            then(resolveFn, rejectFn) {
                if (this.status == 'resolved') { //成功的回調的結果
                    //爲了模仿promise對象中 then方法內的方法是異步的 利用setTimeout
                    setTimeout(() => {
                        let res = resolveFn(this.data) // 接受返回值的結果是promise 仍是 值
                        if (res instanceof myPromise) { // 判斷返回的值是否爲promise構造出來的
                            return res; //若是是 直接返回
                        } else {
                            return myPromise.resolve(res) // 若是不是 返回resolve狀態的值
                        }
                    }, 0)
                }
                if (this.status == 'rejected') { //失敗的回調的結果
                    //爲了模仿promise對象中 then方法內的方法是異步的 利用setTimeout
                    setTimeout(() => {
                        let res = rejectFn(this.data) // 接受返回值的結果是promise 仍是 值
                        if (res instanceof myPromise) { // 判斷返回的值是否爲promise構造出來的
                            return res; //若是是 直接返回
                        } else {
                            return myPromise.resolve(res) // 若是不是 返回resolve狀態的值
                        }
                    }, 0)
                }
                if (this.status == 'pending') { //執行異步的回調函數 如 setTimeout
                    return new myPromise((resolve, reject) => { //首先確定返回promise對象
                        //利用當即執行函數的特性 將每個異步成功的回調插入數組中
                        this.resolveCBArr.push(((resolveFn) => {
                            //return出去一個函數,爲了將裏面的結果映射給 this.resolveCB
                            return () => {
                                let res = resolveFn(this.data);// 接受返回值的結果是promise 仍是值
                                if (res instanceof myPromise) { // 判斷返回的值是否爲promise構造出來的
                                    res.then(resolve, reject) //若是是promise 調用then方法 執行resolve 將狀態映射給new myPromise 返回相應的回調
                                } else {
                                    resolve(res) //若是不是 返回resolve狀態的值
                                }
                            }
                        })(resolveFn))
                        //利用當即執行函數的特性 將每個異步失敗的回調插入數組中
                        this.rejectCBArr.push(((rejectFn) => {
                            //return出去一個函數,爲了將裏面的結果映射給 this.rejectCB
                            return () => {
                                let res = rejectFn(this.data);// 接受返回值的結果是promise 仍是值
                                if (res instanceof myPromise) { // 判斷返回的值是否爲promise構造出來的
                                    res.then(resolve, reject) //若是是promise 調用then方法 執行reject 將狀態映射給new myPromise 返回相應的回調
                                } else {
                                    resolve(res) //若是不是 返回resolve狀態的值
                                }
                            }
                        })(rejectFn))
                    })
                }
            }
            static resolve(data) { //上面的靜態方法 myPromise.resolve()
                return new myPromise(reslove => reslove(data)) //執行封裝好的resolve
            }
            static reject(data) { //上面的靜態方法 myPromise.reject()
                return new myPromise((resolve, reject) => reject(data)) //執行封裝好的reject
            }
            static all(dataArr){ //上面的靜態方法 myPromise.all()
      return new myPromise(resolve => {
          resolve(dataArr) //將傳來的數組添加到data中
      })
    }
    }
--------------------------------------------------------------------------------------------------------------------- 

 總結:

promise的封裝分爲 promise內部的一些方法 如 reslove reject 經過判斷狀態來

決定執行哪一個函數 以及傳輸值能夠將值也輸出 第二部分是原型上面的then方法 then方法

也一樣裏面是兩個回調函數 分別是成功和失敗執行的函數 也是經過 內部方法的狀態來決定

裏面須要判斷的一點是 return出去的值是 promise對象仍是 其餘類型的值 若是是promise

對象下一次調用then方法,是由上一次的return出去的狀態來決定是成功仍是失敗,若是不是

 promise對象的話 能夠直接返回相應的值 第三部分爲promise上面靜態的方法 如Promise.resolve()

這些方法也能夠直接調用 直接返回一個帶有狀態的promise對象就能夠了,最後一點也是最難

理解的一點 就是異步的操做 當promise函數的內部調用 setTimeout 狀態爲pending 咱們

須要特殊的處理一下 保證then方法內能夠依舊執行 咱們須要用一個數組來接收變化的值,而後

配合咱們的當即執行函數來return一個新的函數 將改變以後的狀態映射給 Promise對象 ,最後的

最後 爲了模擬then方法的異步 咱們能夠將resolve reject函數內部添加setTimeout 從而使then

方法內部的函數有一種異步的感受

相關文章
相關標籤/搜索