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

資訊專欄INFORMATION COLUMN

嘗試實(shí)現(xiàn)一個Promise

DTeam / 611人閱讀

摘要:的實(shí)現(xiàn)說明沒有執(zhí)行里的函數(shù)說明執(zhí)行了里的函數(shù)說明執(zhí)行里的函數(shù)過程中出現(xiàn)錯誤和執(zhí)行狀態(tài)時的回調(diào)函數(shù)后返回的結(jié)果都需要執(zhí)行傳進(jìn)來的對象不能等于當(dāng)前的對象回調(diào)返回的值或者的值是對象時需要等待該對象的狀態(tài)變更設(shè)置當(dāng)前狀態(tài)的狀態(tài)和值執(zhí)行回調(diào)隊(duì)列里的函

function resolve_promise_value(promise,value) {//PromiseA+的實(shí)現(xiàn)
    var then;
    /*
        ret false 說明沒有執(zhí)行promise._resolve里的函數(shù)
        ret true 說明執(zhí)行了promise._resolve里的函數(shù)
        ret error 說明執(zhí)行promise._resolve里的函數(shù)過程中出現(xiàn)錯誤
    */
    var ret = false;
    
    /*
        resolve(promise)和執(zhí)行resolve狀態(tài)時的回調(diào)函數(shù)后返回的結(jié)果都需要執(zhí)行resolve(promise,value)
    */
    if (value === promise) {//傳進(jìn)來的對象不能等于當(dāng)前的Promise對象
        promise.reject(new TypeError("TypeError"));
    } else if (value && value instanceof Promise){//回調(diào)返回的值或者resolve的值是Promise對象時需要等待該P(yáng)romise對象的狀態(tài)變更
        value.then(promise.resolve.bind(promise),promise.reject.bind(promise));
    } else if (type(value) === "Object" || type(value) === "Function") {
        try {
            then = value.then;
        } catch(getThenErr) {
            promise.reject(thenErr);
        }
        if (type(then) === "Function") {
            try {
                then.call(value,promise.resolve.bind(promise),promise.reject.bind(promise));
            } catch(callThenErr) {
                if (promise.state === "pending") {
                    promise.reject(callThenErr);
                } 
            }
        } else {
            ret = true;
            var fn;
            promise.setState("fulfilled");//設(shè)置當(dāng)前Promise狀態(tài)的狀態(tài)和值
            promise.value = value;
            var error;
            while (fn = promise._resolve.shift()) {//執(zhí)行resolve回調(diào)隊(duì)列里的函數(shù)
                try {
                    if (typeof fn == "function") {
                        var result = fn(value);
                        promise.value = result;
                    } 
                } catch (err) {
                    ret || (ret = err);//記錄第一個執(zhí)行出錯的函數(shù)的異常信息
                }
            }
        }
    }  else {
        ret = true;
        var fn;
        promise.setState("fulfilled");//設(shè)置當(dāng)前Promise狀態(tài)的狀態(tài)和值
        promise.value = value;
        var error;
        while (fn = promise._resolve.shift()) {//執(zhí)行resolve回調(diào)隊(duì)列里的函數(shù)
            try {
                if (typeof fn == "function") {
                    var result = fn(value);
                    promise.value = result;
                } 
            } catch (err) {
                (ret instanceof Error) || (ret = err);
            }
        }
    }

    if (promise.next) {
        if (ret === true) {
            resolve_promise_value(promise.next,promise.value);
        }
        else if (ret instanceof Error){
            promise.next.reject(ret);    
        }
    }
    
}

function type(arg) {//判斷對象類型函數(shù)
    return  Object.prototype.toString.call(arg).match(/ (w+)/)[1];
}

function Promise(fn,value,state) {
    if (!(this instanceof Promise)) {//防止不用new調(diào)用Promise函數(shù)
        return new Promise(fn);
    }
    this._resolve = [];//Promise對象的fulfilled時執(zhí)行的回調(diào)隊(duì)列
    this._reject = [];//Promise對象的rejected時執(zhí)行的回調(diào)隊(duì)列
    this.next = null;//執(zhí)行下一個Promise對象
    this.value = value || null;//當(dāng)前Promise對象的值
    this.state = state || "pending";//當(dāng)前Promise對象的狀態(tài)
    this.id = Promise.idFactory();
    /*
        new 的時候如果有函數(shù),就執(zhí)行該函數(shù),把resolve和reject函數(shù)作為參數(shù)傳進(jìn)去,并且綁定對應(yīng)的Promise對象
    */
    try {
      fn && fn(this.resolve.bind(this),this.reject.bind(this));
    } catch (e) {
      this.reject(e);
    }
}

Promise.prototype = {
    equal: function(promise) {//根據(jù)id判斷兩個Promise對象是否相等
        return promise && (type(promise.then) === "Function") && (this.id === promise.id);
    },
    resolve: function(value) {
        if(this.state !== "pending"){
            return;
        }
        setTimeout((function() {
            resolve_promise_value(this,value)
        }).bind(this),0);
        
    },
    setState: function(state) {//設(shè)置Promise對象的狀態(tài)
        this.state = state;
    },
    reject: function(value) {
        if (this.state === "pending") {
            setTimeout((function() {
                this.setState("rejected");//設(shè)置Promise對象狀態(tài)
                this.value = value;//記錄Promise對象對應(yīng)的值
                var fn;
                var error;
                if (this._reject.length === 0) {
                    if (this.next) {
                        this.next.reject(value);
                    }
                    return;
                }
                while (fn = this._reject.shift()) {//執(zhí)行reject回調(diào)函數(shù)
                    try {
                        if (typeof fn == "function") {//對于回調(diào)函數(shù)隊(duì)列,只需記錄最后一個函數(shù)的執(zhí)行結(jié)果
                            var result = fn(value);
                            this.value = result;
                        } 
                    } catch (err) {//捕獲異常,保證回調(diào)隊(duì)列里的函數(shù)每一個都被執(zhí)行
                        error || (error = err);
                    }
                }
                if (this.next) {
                    if (error) {
                        this.next.reject(error);
                    } 
                    /*
                        執(zhí)行完當(dāng)前Promise對象的回調(diào)后,如果Promise鏈上有下一個Promise對象,繼續(xù)執(zhí)行,當(dāng)前的Promise對象的值傳進(jìn)去
                        如果error為true則說明上面代碼執(zhí)行中有異常,把異常對象傳給下一個Promise對象
                    */
                    else {
                        resolve_promise_value(this.next,result);
                    }
                }
            }).bind(this),0)
            
        }
    },
    then: function(resolve,reject) {//增加resolve和reject回調(diào)
        if (this.state != "pending") {//如果當(dāng)前Promise對象已經(jīng)resolve或reject則根據(jù)當(dāng)前Promise對象狀態(tài)異步執(zhí)行傳進(jìn)來的resolve或reject函數(shù)
            this.state === "fulfilled" ? (resolve = resolve || function() {}) : (reject = reject || function() {});
            setTimeout(this.state === "fulfilled" ? resolve.bind(null,this.value) : reject.bind(null,this.value),0);
            return;
        }
        (type(resolve) === "Function") && this._resolve.push(resolve);//記錄resolve回調(diào)
        (type(reject) === "Function") && this._reject.push(reject);
        this.next = new Promise();//返回一個新的Promise對象
        return this.next;
    },
    catch: function(reject) {//then(undefined,callback)的語法糖
        return this.then(void 0,reject);
    }
}
Promise.all = function(promiseArr) {
    if (type(promiseArr) !== "Array") {//參數(shù)需要Promise數(shù)組
        new Error("need a Array");
    }
    var count = 0;
    var result = [];//記錄每個Promise的結(jié)果
    var ret = new Promise();//返回新的Promose對象
    for (var i = 0; i< promiseArr.length ;i++) {
        promiseArr[i].then((function(i) {//每個Promise fulfilled后記錄結(jié)果并且判斷是否全部Promise對象已經(jīng)fulfilled
            return function(value) {
                result[i] = value;
                count++;
                if (count === promiseArr.length) {//全部Promise fulfilled的話就執(zhí)行resovle
                    ret.resolve(result); 
                }
            }
        })(i),function(value) {
            if (ret.state === "pending") {//有一個Promise對象reject并且ret還是pending狀態(tài)的話就直接返回
                ret.reject(value);
            }    
        })
    }
    return ret;
}

Promise.race = function(promiseArr) {
    if (type(promiseArr) !== "Array") {
        new Error("need a Array");
    }
    var ret = new Promise();
    for (var i = 0; i< promiseArr.length ;i++) {
        promiseArr[i].then(function(value) {
            if (ret.state === "pending") {//有一個Promise對象resolve的話就返回,并且放棄其余的Promise對象的結(jié)果
                ret.resolve(value);
            }
        },function(value) {
            if (ret.state === "pending") {//有一個Promise對象reject的話就返回,并且放棄其余的Promise對象的結(jié)果
                ret.reject(value);
            }    
        });
    }
    return ret;
}

Promise.resolve = function(arg) {
    if (arg && typeof arg.then === "function") {//參數(shù)是Promise對象的話直接返回
        return arg;
    } else {//否則用參數(shù)構(gòu)造一個Promise對象
        var result = new Promise(null,arg,"fulfilled");
        //result.resolve(arg);
        return result;
    }
}

Promise.reject = function(arg) {//同resolve
    if (arg && typeof arg.then === "function") {
        return arg;
    } else {
        var result = new Promise(null,arg,"reject");
        //result.reject(arg);
        return result;
    }
}
Promise.idFactory = (function() {//id構(gòu)造工廠,id用于比較是否是同一個Promise對象
    var _id = 0;
    return function() {
        return _id += 1;
    }
})();

module.exports = Promise;

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

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

相關(guān)文章

  • PHP下的異步嘗試四:PHP版的Promise

    摘要:結(jié)果打印我結(jié)論或問題這里我們基礎(chǔ)實(shí)現(xiàn)了一個可以用于生產(chǎn)環(huán)境的后續(xù)我們會接續(xù)完善這個的特有方法,比如等后續(xù)再介紹用實(shí)現(xiàn)的自動執(zhí)行器等附錄參考中文對象入門阮一峰 PHP下的異步嘗試系列 如果你還不太了解PHP下的生成器和協(xié)程,你可以根據(jù)下面目錄翻閱 PHP下的異步嘗試一:初識生成器 PHP下的異步嘗試二:初識協(xié)程 PHP下的異步嘗試三:協(xié)程的PHP版thunkify自動執(zhí)行器 PHP下的...

    lentoo 評論0 收藏0
  • [翻譯] Async/Await 使你的代碼更簡潔

    摘要:取而代之,利用事件循環(huán)體系,使用了一種類似語法的工作方式一旦非阻塞的異步操作完成之后,就可以讓開發(fā)者分配的回調(diào)函數(shù)被觸發(fā)。第一個嘗試嵌套的回調(diào)函數(shù)下面是使用嵌套的回調(diào)函數(shù)的實(shí)現(xiàn)方法這可能對于任何使用者來說再熟悉不過了。 寫在文章前 這篇文章翻譯自 ASYNC/AWAIT WILL MAKE YOUR CODE SIMPLER,這是一篇寫于2017年八月的文章,并由某專欄提名為17年十大...

    hightopo 評論0 收藏0
  • Promise 對象初嘗試

    摘要:說到異步操作,可能想到的是這樣以的為例對于的操作來說,是一個異步的過程,通過回調(diào)函數(shù),在得到返回的時候才會去執(zhí)行操作。 showImg(https://segmentfault.com/img/bVtSd1); 瀏覽器支持 showImg(https://segmentfault.com/img/bVtSd8);http://caniuse.com/promises/embed/age...

    haoguo 評論0 收藏0
  • 一篇文章用ES6手?jǐn)]一個Promise

    摘要:本篇文章將會嘗試用簡單易懂的語言描述的原理,并且用手?jǐn)]一個簡單的。一個后可以通過方法,指定和時的回調(diào)函數(shù)。實(shí)現(xiàn)實(shí)現(xiàn)狀態(tài)機(jī)因?yàn)槭且粋€構(gòu)造函數(shù),使用的寫法,首先想到的就是有顯式聲明的。 說到Promise,都知道它是比回調(diào)函數(shù)更優(yōu)的一種異步編程解決方案,它可以使得異步操作邏輯變得更加清晰,是解決地獄回調(diào)的一種嘗試。本篇文章將會嘗試用簡單易懂的語言描述Promise的原理,并且用es6手?jǐn)]一...

    hsluoyz 評論0 收藏0
  • 一篇文章帶你嘗試拿下js異步

    摘要:單線程就意味著,所有任務(wù)需要排隊(duì),前一個任務(wù)結(jié)束,才會執(zhí)行后一個任務(wù)。這決定了它只能是單線程,否則會帶來很復(fù)雜的同步問題。小結(jié)本身是單線程的,并沒有異步的特性。當(dāng)異步函數(shù)執(zhí)行時,回調(diào)函數(shù)會被壓入這個隊(duì)列。 走在前端的大道上 本篇將自己讀過的相關(guān) js異步 的文章中,對自己有啟發(fā)的章節(jié)片段總結(jié)在這(會對原文進(jìn)行刪改),會不斷豐富提煉總結(jié)更新。 概念 JS 是單線程的語言。 單線程就意味著...

    MartinDai 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<