成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

自己如何實(shí)現(xiàn)promise?

kycool / 801人閱讀

摘要:如果讓你實(shí)現(xiàn)一個(gè)你會(huì)怎么做自己實(shí)現(xiàn)的大體思路我們要明確我們需要一個(gè)異步的操作方法滿(mǎn)足異步回調(diào)。所以選擇加入作為實(shí)現(xiàn)的基礎(chǔ),讓函數(shù)實(shí)現(xiàn)延遲觸發(fā)。測(cè)試代碼測(cè)試第二版實(shí)現(xiàn)返回一個(gè)觸發(fā)返回一個(gè)觸發(fā)

如果讓你實(shí)現(xiàn)一個(gè) promise ,你會(huì)怎么做?

自己實(shí)現(xiàn)promise的大體思路

我們要明確我們需要一個(gè)異步的操作方法,滿(mǎn)足異步回調(diào)。所以選擇加入setTimeout 作為實(shí)現(xiàn)的基礎(chǔ), 讓函數(shù)實(shí)現(xiàn)延遲觸發(fā)。

保持一個(gè)原則,控制 promise 改變狀態(tài)的只有 promise 構(gòu)造函數(shù)里的 reslove 、 reject 函數(shù)。

鏈?zhǔn)秸{(diào)用的原理, 類(lèi)似jQuery,它會(huì)在調(diào)用方法后, return this. 從而形成鏈?zhǔn)秸{(diào)用。所以我們采用在調(diào)用then(fn)、 catch(fn) 后 會(huì)返回一個(gè)新的 promise 對(duì)象, 然而 這個(gè) promise 對(duì)象 受到 它的上級(jí)promise 對(duì)象的狀態(tài)結(jié)果 和 fn 運(yùn)行結(jié)果的控制。

知識(shí)點(diǎn):
里面 應(yīng)該 用到點(diǎn) js 作用域 、 函數(shù)閉包、 繼承 、 上下文 綁定知識(shí)、引用傳遞。

存在問(wèn)題

cbList、rhList、 cs 這個(gè)三個(gè), Promise 對(duì)象能直接訪問(wèn), 如果對(duì)其直接操作可能造成 程序紊亂。

代碼如有紕漏,望大家指正

var JcPromise = function (fn) {
    // 防止 用戶(hù) 直接 更改 state
    var state = "wait"
     // state 為 resolve 狀態(tài), 回調(diào)函數(shù)數(shù)組
    var cbList = []
     // state 為 reject 狀態(tài), 回調(diào)函數(shù)數(shù)組
    var rjList = []
    this.cbList = cbList
    this.rjList = rjList
    // 
    this.cs = undefined
    // 獲取 promise 的狀態(tài)
    this.getState = function () {
        return state
    }
    /* 函數(shù)閉包,函數(shù) 定義在里面, 防止 外面用戶(hù) 直接 使用 resolve 和 reject; */
    // Promise成功觸發(fā) 函數(shù)
    var reslove = function (data) {
        this.cs = data
        if (state !== "wait") {
            return
        } else {
            state = "solve"
            while (this.cbList.length) {
                cbList.shift()(data)
            }
        }
    }
   // Promise 拒絕 觸發(fā)函數(shù)
    var reject = function (e) {
        this.cs = e
        if (state !== "wait") {
            return
        } else {
            state = "reject"
            while (rjList.length) {
                rjList.shift()(e)
            }
        }
    }
// 綁定函數(shù) conext 及 this 為當(dāng)前 promise對(duì)象
    reslove = reslove.bind(this)
    reject = reject.bind(this)
// 延遲 觸發(fā)
    setTimeout(function () {
        fn(reslove, reject)
    }, 0)
}
JcPromise.prototype.then = function (fn) {
    var handleObj = {}
    var nextPromise = new JcPromise(function (r, j) {
        handleObj.r = r
        handleObj.j = j
    })
    var fixFn = function (data) {
        var result = null
        try {
            result = fn(data)
              // 判斷result是不是 JcPromise實(shí)例。
            if (result instanceof JcPromise) {
                result.then(function (data) {
                    handleObj.r(data)
                }).catch(function (e) {
                    handleObj.j(e)
                })
            } else  {
                handleObj.r(result)
            }
        } catch (e){
            handleObj.j(e)
        }
    }
    //判斷當(dāng)前狀態(tài) 如果 是 solve 直接 運(yùn)行, 如果不是,酒吧 fixFn 推入 cbList 數(shù)組。
    if (this.getState() === "solve") {
        setTimeout(function () {
            fixFn(this.cs)
        }, 0)
    } else {
        this.cbList.push(fixFn)
    }
    return nextPromise
}
JcPromise.prototype.catch = function (fn) {
    var handleObj = {}
    var nextPromise = new JcPromise(function (r, j) {
        handleObj.r = r
        handleObj.j = j
    })
    var fixFn = function (e) {
        var result = null
        try {
            result = fn(e)
            if (result instanceof JcPromise) {
                result.then(function (data) {
                    handleObj.r(data)
                }).catch(function (e) {
                    handleObj.j(e)
                })
            } else {
                handleObj.r(result)
            }
        } catch (e){
            handleObj.j(e)
        }
    }
    if (this.getState() === "reject") {
        setTimeout(function () {
            fixFn(this.cs)
        }, 0)
    } else {
        this.rjList.push(fixFn)
    }
    return nextPromise
}
// 測(cè)試代碼
var p = new JcPromise(function(r, j) {
    setTimeout(function() {r(100)}, 3000)
}).then(data => {
    console.log("1", data)
    return new JcPromise((r, j) => {
        setTimeout(() => {
            r("hi")
        }, 3000)
    })
}).then(data => console.log("2", data)).then(function () {
    console.log("xxx", xx + 1)
}).catch(e => console.log(e)).then(data => console.log(data, "end"))

demo 測(cè)試
第二版 jcPromise 實(shí)現(xiàn)

    var JcPromise = (function() {
        function JcPromise(fn) {
            fn = fn || noop;
            var statusList = ["start", "pending", "succeed", "err"];
            var cbStatus = [0, 1];
            var status = statusList[0];
            var data = null;
            var err = null;
            var that = this;
            var successFn = [];
            var errFn = [];

            function resolve(d) {
                data = d;
                that._changeStatus(2);
            };

            function reject(e) {
                err = e;
                that._changeStatus(3);
            };
            this.getData = function() {
                return data;
            };
            this.getErr = function() {
                return err
            };
            this.getStatus = function() {
                return status
            };
            this._changeStatus = function(idx) {
                switch (status) {
                    case statusList[2]:
                    case statusList[3]:
                        {
                            return false
                        }
                };
                status = statusList[idx];
                if (status === statusList[3]) {
                    setTimeout(function() {
                        that._triggerCatch();
                    }, 0)
                }
                if (status === statusList[2]) {
                    setTimeout(function() {
                        that._triggerThen();
                    }, 0)
                }
            };
            this._pushThenCb = function(cb) {
                successFn.push({
                    status: cbStatus[0],
                    cb: cb
                });
                if (status === statusList[2]) {
                    this._triggerThen();
                }
            };
            this._pushCatchCb = function(cb) {
                errFn.push({
                    status: cbStatus[0],
                    cb: cb
                });
                if (status === statusList[3]) {
                    this._triggerCatch();
                }
            };
            this._triggerThen = function() {
                successFn.map(function(item) {
                    if (item.status === cbStatus[0]) {
                        item.cb(data);
                        item.status = cbStatus[1];
                    }
                })
            };
            this._triggerCatch = function() {
                errFn.map(function(item) {
                    if (item.status === cbStatus[0]) {
                        item.cb(err);
                        item.status = cbStatus[1];
                    }
                })
            };
            this._changeStatus(1);
            this.uuid = uuid++;
            try {
                fn(resolve, reject);
            } catch (e) {
                reject(e)
            }
            return this
        };
        JcPromise.fn = JcPromise.prototype;
        // 返回一個(gè)promise
        JcPromise.fn.then = function(cb) {
            var promiseR = null;
            var promiseJ = null;
            var result = null;
            var that = this;
            var fn = function() {
                setTimeout(function() {
                    try {
                        var data = that.getData();
                        result = cb(data);
                        if (typeof result === "object" && result !== null && result.constructor === JcPromise) {
                            result.then(function(data) {
                                promiseR(data)
                            }).catch(function(e) {
                                promiseJ(e)
                            })
                        } else {
                            promiseR(result)
                        }
                    } catch (e) {
                        promiseJ(e)
                    }
                }, 0);
            };
            this._pushThenCb(fn);
            // 觸發(fā)promise
            return new JcPromise(function(r, j) {
                promiseR = r;
                promiseJ = j;
            });
        };
        // 返回一個(gè)promise
        JcPromise.fn.catch = function(cb) {
            var promiseR = null;
            var promiseJ = null;
            var result = null;
            var that = this;
            var fn = function() {
                setTimeout(function() {
                    try {
                        var data = that.getErr();
                        result = cb(data);
                        if (typeof result === "object" && result !== null && result.constructor === JcPromise) {
                            result.then(function(data) {
                                promiseR(data)
                            }).catch(function(e) {
                                promiseJ(e)
                            })
                        } else {
                            promiseR(result)
                        }
                    } catch (e) {
                        promiseJ(e)
                    }
                }, 0)
            };
            this._pushCatchCb(fn);
            // 觸發(fā)promise
            return new JcPromise(function(r, j) {
                promiseR = r;
                promiseJ = j;
            });
        };
        return JcPromise
    })();

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93453.html

相關(guān)文章

  • JavaScript 異步

    摘要:從最開(kāi)始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。寫(xiě)一個(gè)符合規(guī)范并可配合使用的寫(xiě)一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來(lái)處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問(wèn)題描述 在開(kāi)發(fā)過(guò)程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過(guò)http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過(guò)...

    tuniutech 評(píng)論0 收藏0
  • 高級(jí)前端面試題大匯總(只有試題,沒(méi)有答案)

    摘要:面試題來(lái)源于網(wǎng)絡(luò),看一下高級(jí)前端的面試題,可以知道自己和高級(jí)前端的差距。 面試題來(lái)源于網(wǎng)絡(luò),看一下高級(jí)前端的面試題,可以知道自己和高級(jí)前端的差距。有些面試題會(huì)重復(fù)。 使用過(guò)的koa2中間件 koa-body原理 介紹自己寫(xiě)過(guò)的中間件 有沒(méi)有涉及到Cluster 介紹pm2 master掛了的話pm2怎么處理 如何和MySQL進(jìn)行通信 React聲明周期及自己的理解 如何...

    kviccn 評(píng)論0 收藏0
  • 2018大廠高級(jí)前端面試題匯總

    摘要:面試的公司分別是阿里網(wǎng)易滴滴今日頭條有贊挖財(cái)滬江餓了么攜程喜馬拉雅兌吧微醫(yī)寺庫(kù)寶寶樹(shù)??低暷⒐浇挚峒覙?lè)百分點(diǎn)和海風(fēng)教育。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本人于7-8月開(kāi)始準(zhǔn)備面試,過(guò)五關(guān)斬六將,最終抱得網(wǎng)易歸,深深感受到高級(jí)前端面試的套路。以下是自己整理的面試題匯總,不敢藏私,統(tǒng)統(tǒng)貢獻(xiàn)出來(lái)。 面試的公司分...

    zzir 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

kycool

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<