手寫簡易Promise

孤城寒發表於2019-04-10

前言

首先,我是一名大四前端小白,如果以下內容有錯誤或值得改進的地方,還請各位大佬多多指點哈(瘋狂吐槽)

Promise相信大家肯定相當熟悉,但對於像我剛入門的小白來說,想完全理解Promise的內部原理還是挺困難的。

Promise 物件擁有很強大的功能,它允許你為非同步操作的成功和失敗分別繫結相應的處理方法。 這讓非同步操作可以像同步操作一樣返回值,但並不是立即返回最終執行結果,而是一個能代表未來出現的結果的promise物件,Promise有以下幾種狀態:

pending: 初始狀態,狀態變化前的就緒狀態。
fulfilled: 意味著操作成功完成。
rejected: 意味著操作失敗。
複製程式碼

pending狀態的promise物件可能轉變為fulfilled狀態,也可能轉變rejected狀態。在這個狀態轉變的過程中,狀態的變化是不可逆的。狀態一旦改變,Promise物件的then方法繫結的處理方法就會被呼叫。

coding

瞭解以上的內容基本上就可以實現一個簡易的promise物件,程式碼:

        //簡易promise實現(resolve,reject)
        function promise(fn) {
            this.value = undefined // 成功狀態值
            this.err = undefined // 失敗狀態值
            this.status = 'pending' // 開始狀態(就緒)
            var t = this
            // 就緒 -> 成功
            function resolve(val) {
                if (t.status === 'pending') {
                    t.value = val
                    t.status = 'success'
                }
            }
            // 就緒 -> 失敗
            function reject(err) {
                if (t.status === 'pending') {
                    t.err = err
                    t.status = 'fail'
                }
            }
            fn(resolve, reject)
        }
        promise.prototype.then = function(isSuccess, isFail) {
            var t = this
            // 實現promise的鏈式呼叫
            return new promise(function(resolve, reject) {
                // 用setTimeout模擬實現then方法的非同步操作
                setTimeout(function() {
                    if (t.status === 'success') {
                        // 將then1回撥函式返回的值傳給then2回撥函式,以此類推
                        resolve(isSuccess(t.value))
                    }
                    if (t.status === 'fail') {
                        reject(isFail(t.err))
                    }
                })
            })

        }
        
        // test 
        var p = new promise(function(resolve, reject) {
            if (1) {
                resolve("test resolve success")
            } else {
                reject("test rejecr fail")
            }

        })
        p.then(function(val) {
            console.log(val)
            return val + "鏈式呼叫return"
        }).then(function(val) {
            console.log(val)
        })
        
        // test resolve success
        // test resolve success鏈式呼叫return
複製程式碼

從上面的程式碼可以看出我只是簡單實現了resolve、reject的功能,並沒有考慮異常,和多個resolve回撥的處理情況。在後續的學習中,會逐步實現一個完整的promise物件(好難,哈哈!)

結論

promise在非同步程式設計中的使用是相當廣泛的,剛入門的前端小白對於非同步程式設計理解的不是很透徹,希望通過此例子對非同步程式設計思想有一個更深刻的認識,如:even loop。

相關文章