亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Promise 規(guī)范解讀及實(shí)現(xiàn)細(xì)節(jié) (二)

Michael_Lin / 3500人閱讀

摘要:開(kāi)始前的實(shí)現(xiàn)原理已經(jīng)在規(guī)范解讀及實(shí)現(xiàn)細(xì)節(jié)一中說(shuō)的很清楚了,這里將詳細(xì)分析規(guī)范中的解析過(guò)程,最后會(huì)實(shí)現(xiàn)一個(gè)并提供用于測(cè)試的代碼方法分析這里的調(diào)用會(huì)產(chǎn)生一個(gè)新的不同實(shí)例對(duì)于上一級(jí)的終值會(huì)作為的參數(shù)被傳入對(duì)于如果返回一個(gè)返回一個(gè)那么的狀態(tài)和值由決

開(kāi)始前

Promise的實(shí)現(xiàn)原理已經(jīng)在 Promise 規(guī)范解讀及實(shí)現(xiàn)細(xì)節(jié) (一) 中說(shuō)的很清楚了,這里將詳細(xì)分析 Promises/A+規(guī)范 中的Promise解析過(guò)程,最后會(huì)實(shí)現(xiàn)一個(gè) Promise 并提供用于測(cè)試的代碼

then 方法分析

promise.then(fn1).then(fn2).then(fn3) 這里 promise.then() 的調(diào)用會(huì)產(chǎn)生一個(gè)新的promise(不同實(shí)例)

對(duì)于 then(fn) 上一級(jí) promise 的終值會(huì)作為 fn 的參數(shù)被傳入

對(duì)于 then(fn) 如果 then 返回一個(gè) promise1,fn 返回一個(gè) promise2 那么 promise1 的狀態(tài)和值由 promise2 決定

對(duì)于 then(fn) 如果 then 返回一個(gè) promise1,fn 返回一個(gè) promise2 我們想依賴(lài)于promise2 的調(diào)用會(huì)被添加到 promise1

如何讓 promise2 決定 promise1 的結(jié)果

如果promise2thenvar promise2Then = promise2.then,我們這樣promise2Then.bind(promise1,resolve,reject)

promise 的狀態(tài)和終值都是通過(guò) 當(dāng)前 promiseresolvereject 來(lái)改變的,所以只需要將 promise1 的這兩個(gè)函數(shù)通過(guò)promise2then 方法添加的 promise2 的執(zhí)行隊(duì)列中就可以達(dá)到想要的效果

Promise 解析過(guò)程

對(duì)于 promise.then(fn),then 方法返回 promise1,fn 方法返回 x,fn 接收到的參數(shù)為 y,這時(shí)需要對(duì) xy 分別運(yùn)行Promise解析過(guò)程

x: [[Resolve]](promise1, x)
y: [[Resolve]](promise1, y)
x 的解析過(guò)程處理的是 回掉中返回 promise 的情況
y 的解析過(guò)程處理的是 向當(dāng)前 promise 傳遞處理結(jié)果的那個(gè) promise 的終值是 promise 的情況

由此可見(jiàn) promise 的解析過(guò)程是遞歸的,遞歸的終點(diǎn)是 x,y 不是promise,在是對(duì)象或者函數(shù)的情形下不具備 then 方法

代碼結(jié)構(gòu)
(function(window) {
    var PENDING = 0; //PENDING 狀態(tài)
    var RESOLVED = 1; //RESOLVED 狀態(tài)
    var REJECTED = 2; //REJECTED 狀態(tài)
    function IPromise(fn) {
        if (!(this instanceof IPromise)) return new IPromise(fn); //確保 通過(guò) new IPromise() 和 IPromise() 都能正確創(chuàng)建對(duì)象
        var state = PENDING; //promise 狀態(tài)
        var value = null; //終值
        var callback = []; //回掉函數(shù)隊(duì)列,在一種是兩個(gè)隊(duì)列,這里是一個(gè),所以存放的是對(duì)象

        function reject(reason) {} //reject 方法
        function resolve(result) {} //和(一)中的對(duì)比 這里多了 執(zhí)行 Promise 解析過(guò)程 的功能
        function handle(handler) {} //添加或執(zhí)行隊(duì) callback 中的調(diào)用

        /**
        *@param onFulfilled 通過(guò) then 方法添加的 onFulfilled
        *@param onRejected 通過(guò) then 方法添加的 onRejected
        *
        *@func 包裝用戶添加的回調(diào) 
        *因?yàn)檫@里只有一個(gè)回掉隊(duì)列所以需要用 candy(糖果) 包裝成{onFulfilled:onFulfilled,onRejected:onRejected}
        *
        *@func 延遲調(diào)用handle
        *在 Promise 規(guī)范解讀及實(shí)現(xiàn)細(xì)節(jié) (一) 中說(shuō) Promise(瀏覽器實(shí)現(xiàn)) 會(huì)被加入到microtask,由于瀏覽器沒(méi)有提供除Promise
        *之外microtask的接口,所以 我們要用 setTimeout 來(lái)延遲調(diào)用并添加到 macrotask
        *
        */
        function candy(onFulfilled, onRejected) {}

        function getThen(value) {} //判斷 value 是否有 then 方法如果有則獲取

        this.then = function(onFulfilled, onRejected) {} //暴露的 then 方法
        doResolve(fn, resolve, reject); //執(zhí)行 fn
        window.IPromise = IPromise; //將 IPromise 添加到瀏覽器的 window 上
    }
    /**
    *Promise 解析過(guò)程
    */
    function doResolve(fn, resolvePromise, rejectPromise) {} //靜態(tài)私有方法,解析并執(zhí)行promise(解析并執(zhí)行fn和promise的處理結(jié)果)
})(window);

以上通過(guò) js 自執(zhí)行函數(shù)將變量和函數(shù)限制在了作用域中,在全局的 window 上只暴露一個(gè)構(gòu)造函數(shù) IPromise 保證了全局不被污染

具體代碼及解釋(請(qǐng)?jiān)跒g覽器中運(yùn)行)
/**
 *@author ivenj
 *@date 2016-12-06
 *@version 1.0 
 */
(function(window) {
    var PENDING = 0;
    var RESOLVED = 1;
    var REJECTED = 2;

    function IPromise(fn) {
        if (!(this instanceof IPromise)) return new IPromise(fn);
        var state = PENDING;
        var value = null;
        var callback = [];

        function reject(reason) {
            state = REJECTED;
            value = reason;
            callback.forEach(handle);
            callback = null;
        }

        /**
        * 這里新增的內(nèi)容是 滿足Promise解析過(guò)程時(shí) resolve和doResolve相互調(diào)用形成遞歸
        **/
        function resolve(result) {
            try {
                var then = getThen(result);
                if (then) {
                    doResolve(then.bind(result), resolve, reject);  //aa
                    return; //這里如果 resule 是有 then 方法則執(zhí)行 doResolve 并返回不執(zhí)行后續(xù)代碼
                }
                //只有 result 不滿足 解析過(guò)程時(shí)執(zhí)行,即遞歸終點(diǎn)
                state = RESOLVED;
                value = result;
                callback.forEach(handle);
                callback = null;
            } catch (e) {
                reject(e);
            }
        }

        function handle(handler) {
            if (state === PENDING) {
                callback.push(handler);
            } else {
                if (state === RESOLVED && typeof handler.onFulfilled === "function") {
                    handler.onFulfilled(value);
                }
                if (state === REJECTED && typeof handler.onRejected === "function") {
                    handler.onRejected(value);
                }
            }
        }

        function candy(onFulfilled, onRejected) {
            setTimeout(function() {
                handle({
                    onFulfilled: onFulfilled,
                    onRejected: onRejected
                });
            }, 0);
        }

        function getThen(value) {
            var type = typeof value;
            if (value && (type === "object" || type === "function")) {
                try{
                    var then = value.then;
                }catch(e){
                    reject(e);
                }
                if (typeof then === "function") {
                    return then;
                }
            }
            return null;
        }

        this.then = function(onFulfilled, onRejected) {
            var self = this;
            return new IPromise(function(resolve, reject) {
                candy(function(x) {
                    if (typeof onFulfilled === "function") {
                        try {
                            resolve(onFulfilled(x)); //cc 運(yùn)行 [[Resolve]](promise, x)
                        } catch (e) {
                            reject(e);
                        }
                    } else {
                        resolve(x);
                    }
                }, function(error) {
                    if (typeof onRejected === "function") {
                        try {
                            resolve(onRejected(error));
                        } catch (e) {
                            reject(e);
                        }
                    } else {
                        reject(error);
                    }
                });
            });
        };
        doResolve(fn, resolve, reject);
    }

    /**
    *Promise 解析過(guò)程
    */
    function doResolve(fn, resolvePromise, rejectPromise) {
        var done = false; //用于保證只調(diào)用一次
        try {
            fn(function(y) {
                if (done) return;
                done = true;
                resolvePromise(y); //bb 如果 resolvePromise 以值 y 為參數(shù)被調(diào)用,則運(yùn)行 [[Resolve]](promise, y)
            }, function(reason) {
                if (done) return;
                done = true;
                rejectPromise(reason);
            });
        } catch (e) {
            if (done) return;
            done = true;
            rejectPromise(e);
        }
    }
    window.IPromise = IPromise;
})(window);

這里是用于測(cè)試的代碼 讀者將以上代碼和以下代碼粘貼到瀏覽器去運(yùn)行 一秒后會(huì)打印 {url: "http://ivenj_", value: 10}

function post(url, callback) {
    setTimeout(function() {
        var data = { //模擬異步處理結(jié)果
            url:url,
            value:10
        };
        callback(data);
    }, 1000);
}

var promise = IPromise(function(resolve, reject){
    post("http://ivenj_", function(data){
        resolve(data);
    });
});

promise.then(function(data){
    console.log(data);
});

Promise 實(shí)現(xiàn)最核心的內(nèi)容是代碼中的 //aa //bb //cc 讀者需要著重體會(huì)這三處
Promise 到此已經(jīng)結(jié)束

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

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

相關(guān)文章

  • Promise 規(guī)范解讀實(shí)現(xiàn)細(xì)節(jié) (一)

    摘要:宏任務(wù)和微任務(wù)這兩個(gè)是指兩個(gè)隊(duì)列,腳本整體代碼的回調(diào)及渲染都會(huì)被加入到隊(duì)列中回調(diào)瀏覽器實(shí)現(xiàn)回調(diào)都會(huì)被加入到隊(duì)列。 1. macrotask (宏任務(wù))和 microtask (微任務(wù)) 這兩個(gè)是指兩個(gè)隊(duì)列,腳本整體代碼、setTimeout、setInterval、setImmediate、I/O、的回調(diào)及UI渲染都會(huì)被加入到 macrotask 隊(duì)列中, process.nextTi...

    gougoujiang 評(píng)論0 收藏0
  • 理解 Promise 的工作原理

    摘要:前兩個(gè)函數(shù)對(duì)應(yīng)的兩種狀態(tài)和的回調(diào)函數(shù)。返回值是和對(duì)應(yīng)的方法,但是會(huì)在下一事件循環(huán)返回。此外,在規(guī)范中,由方法生成的對(duì)象是已執(zhí)行還是已拒絕,取決于由方法調(diào)用的那個(gè)回調(diào)是返回值還是拋出錯(cuò)誤。但是對(duì)于其工作原理卻有些懵懂和好奇。 原文: https://blog.coding.net/blog/how-do-promises-work Javascript 采用回調(diào)函數(shù)(callback)來(lái)...

    Achilles 評(píng)論0 收藏0
  • Promises A+規(guī)范原文解讀 + es6實(shí)現(xiàn)(附詳細(xì)注釋?zhuān)?/b>

    摘要:英文官方文檔原文前言寫(xiě)本文的目的,是為了更好的理解,通過(guò)解讀翻譯原文,逐行解析原文通過(guò)代碼一行一行實(shí)現(xiàn)。英中原因是一個(gè)值結(jié)果表明被拒絕的原因。英中在法律允許的范圍內(nèi),組織已放棄所有版權(quán)及規(guī)范的相關(guān)或相鄰權(quán)利。 英文官方文檔原文:https://promisesaplus.com/ 前言 寫(xiě)本文的目的,是為了更好的理解promise,通過(guò)解讀翻譯原文,逐行解析原文通過(guò)代碼一行一行實(shí)現(xiàn)。...

    v1 評(píng)論0 收藏0
  • 超詳細(xì)的webpack原理解讀

    摘要:生成文件,是模塊構(gòu)建的終點(diǎn),包括輸出文件與輸出路徑。這里配置了處理各模塊的,包括預(yù)處理,編譯,圖片處理。各插件對(duì)象,在的事件流中執(zhí)行對(duì)應(yīng)的方法。修改改成引入模塊在目錄下執(zhí)行, webpack原理解讀 本文抄自《深入淺出webpack》,建議想學(xué)習(xí)原理的手打一遍,操作一遍,給別人講一遍,然后就會(huì)了在閱讀前希望您已有webpack相關(guān)的實(shí)踐經(jīng)驗(yàn),不然讀了也讀不懂 本文閱讀需要幾分鐘,理解需...

    wenhai.he 評(píng)論0 收藏0
  • 一步一步實(shí)現(xiàn)一個(gè)符合PromiseA+規(guī)范Promise庫(kù)(2)

    摘要:我們都知道,方法中有和兩個(gè)回調(diào)函數(shù),所以我們要處理一下這兩個(gè)回調(diào)函數(shù)。我們實(shí)現(xiàn)了異步調(diào)用,在方法中返回或者值,實(shí)現(xiàn)了方法中可以沒(méi)有回調(diào)函數(shù)也能把執(zhí)行結(jié)果傳入下一次的方法中。 Hello everybody。我又來(lái)啦,還記得我們上一張實(shí)現(xiàn)的內(nèi)容嗎? showImg(https://segmentfault.com/img/bV6UaU?w=102&h=95); 上一張我們實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的...

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

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

0條評(píng)論

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