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

資訊專欄INFORMATION COLUMN

ES6 異步編程之三:Generator續(xù)

JiaXinYi / 2922人閱讀

摘要:前言在異步編程之一中實現(xiàn)了一個異步函數(shù)調用鏈,它是一個順序調用鏈,很類似責任鏈模式,但現(xiàn)實往往不是平鋪直敘的,更多的其實是峰回路轉,本文將繼續(xù)討論更多的用法。

前言

在《ES6 異步編程之一:Generator》中實現(xiàn)了一個異步函數(shù)調用鏈,它是一個順序調用鏈,很類似責任鏈模式,但現(xiàn)實往往不是平鋪直敘的,更多的其實是峰回路轉,本文將繼續(xù)討論更多Generator的用法。

作為函數(shù)的Generator

在之前的示例中,我們更多的是把生成器作為一個迭代器來循環(huán)調用每個函數(shù),但忽視了生成器也是個函數(shù),意味著生成器內(nèi)部可以實現(xiàn)復雜的業(yè)務邏輯,以下的代碼通過yield等待文件讀取結果并對結果進行特定的處理,

    function* generator() {
        let r1 = yield get("a");
        if (r1) {
            let r2 = yield get("b");
            if (r2) {
                console.log(yield get("d"));
            }
        } else {
            console.log(yield get("c"));
        }
    }
    
    let g = generator();
    g.next();

如果get是個異步調用,以上的代碼想要能夠執(zhí)行則需要get函數(shù)執(zhí)行得到結果后調用生成器的next方法來推進,這要求get函數(shù)能持有生成器對象,這顯然并不容易。

偏函數(shù)

偏函數(shù)(Partial Function)是對函數(shù)定義域的子集定義的函數(shù),形式上就是指定任意部分參數(shù)生成一個新的函數(shù),如下:

    function sum(a, b, c) {
        return a + b + c;
    }
    
    function sum1(a) {
        return function(b, c) {
            return a + b + c;
        };
    }
    
    function sum2(a, b) {
        return function(c) {
            return a + b + c;
        };
    }
    
    sum(1, 2, 3) == sum1(1)(2, 3); //true
    sum(1, 2, 3) == sum2(1, 2)(3); //true

一般在設計異步調用api時,我們總是聲明一個參數(shù)來接收回調函數(shù),當和偏函數(shù)相結合就變成這樣:

    function get(f, callback) {
        delay(100, function(s) {
            callback(s + ":get " + f);
        });
    }
    
    get("a", func);  //調用get時必須立即傳入一個函數(shù)
    
    //轉換成偏函數(shù)形式:
    function partialGet(f) {
        return function(callback) {
            delay(100, function(s) {
                callback(s + ":get " + f);
            });
        };
    }
    
    let pGet = partialGet("a");   //可以先生成一個函數(shù)
    pGet(func);  //需要時再傳入回調函數(shù)執(zhí)行

從上面的例子中可以發(fā)現(xiàn),偏函數(shù)能使定義和執(zhí)行分離,說來巧了,生成器可用于定義業(yè)務邏輯而生成器的next用于推進業(yè)務執(zhí)行,二者也是相互分離的。

生成器和偏函數(shù)

基于前面這么多鋪墊,假設get就是一個偏函數(shù),如下:

    function get(f) {
        return function(callback) {
            delay(100, function(s) {
                callback(s + ":get " + f);
            });
        };
    }

這意味著,yield get("a")使得next函數(shù)執(zhí)行的結果其value屬性值是個函數(shù),該函數(shù)的參數(shù)是一個能接收get異步結果的回調函數(shù),即:

    g.next().value(function(value) {
        g.next(value); //value成為yield的返回并繼續(xù)推進業(yè)務邏輯
    });

通過遞歸可以不斷的執(zhí)行生成器的next方法,一個全新的通過生成器來實現(xiàn)業(yè)務邏輯的run方法便呼之欲出了,

function run(gen) {
    let g = gen();

    function next(lastValue) {
        let result = g.next(lastValue); //將上一個異步執(zhí)行結果傳出給當前的yield并執(zhí)行下一個yield
        if (result.done) {
            return result.value;
        }
        //value是偏函數(shù)返回的新函數(shù),它的參數(shù)是個用來接收異步結果的回調函數(shù)
        result.value(next);  //next作為接收異步結果的回調函數(shù)
    }

    next();
}

run(generator);

綜合以上例子不難發(fā)現(xiàn)另外一個好處,通過偏函數(shù)可以使異步調用api不受生成器的侵入,《ES6 異步編程之一:Generator》中實現(xiàn)的異步調用需要將生成器作為參數(shù),有興趣的話你可以嘗試改造一下之前的示例。

現(xiàn)在通過新編寫的run函數(shù)就可以來執(zhí)行本文一開始編寫的那個生成器了。

thunkify

偏函數(shù)的方案對api和生成器也是有侵入的,他要求:

api必須是偏函數(shù)形式;

生成器定義業(yè)務邏輯,每個yield 后面的函數(shù)必須是調用偏函數(shù);

第二個問題是本方案的核心機制所要求,但第一個問題我們可以通過thunkify來解決,api依舊按照get(value, callback)方式定義,但定義生成器時需要將異步api調用通過thunkify轉換為偏函數(shù),如下:

    let Thunkify = require("thunkify");
    
    let thunkifiedGet = Thunkify(get);
    
    function get(f, callback) {
        delay(100, function(s) {
            callback(s + ":get " + f);
        });
    
    }
    
    function* generator() {
        let r1 = yield thunkifiedGet("a");
        if (r1) {
            let r2 = yield thunkifiedGet("b");
            if (r2) {
                console.log(yield thunkifiedGet("d"));
            }
        } else {
            console.log(yield thunkifiedGet("c"));
        }
    }

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

轉載請注明本文地址:http://systransis.cn/yun/81484.html

相關文章

  • 談談ES6前后的異步編程

    摘要:回調函數(shù)這是異步編程最基本的方法。對象對象是工作組提出的一種規(guī)范,目的是為異步編程提供統(tǒng)一接口。誕生后,出現(xiàn)了函數(shù),它將異步編程帶入了一個全新的階段。 更多詳情點擊http://blog.zhangbing.club/Ja... Javascript 語言的執(zhí)行環(huán)境是單線程的,如果沒有異步編程,根本沒法用,非卡死不可。 為了解決這個問題,Javascript語言將任務的執(zhí)行模式分成兩種...

    fizz 評論0 收藏0
  • ES6&ES7中的異步Generator函數(shù)與異步編程

    摘要:傳統(tǒng)的異步方法回調函數(shù)事件監(jiān)聽發(fā)布訂閱之前寫過一篇關于的文章,里邊寫過關于異步的一些概念。內(nèi)部函數(shù)就是的回調函數(shù),函數(shù)首先把函數(shù)的指針指向函數(shù)的下一步方法,如果沒有,就把函數(shù)傳給函數(shù)屬性,否則直接退出。 Generator函數(shù)與異步編程 因為js是單線程語言,所以需要異步編程的存在,要不效率太低會卡死。 傳統(tǒng)的異步方法 回調函數(shù) 事件監(jiān)聽 發(fā)布/訂閱 Promise 之前寫過一篇關...

    venmos 評論0 收藏0
  • JavaScript異步操作(續(xù)

    摘要:環(huán)境中產(chǎn)生異步操作的函數(shù)分為兩大類計時函數(shù)和函數(shù)。如果要在應用中定義復雜的異步操作,就要使用者兩類異步函數(shù)作為基本的構造快。在本例子中同步事件循環(huán)不包含內(nèi)部的外部的異步事件循環(huán)內(nèi)部的。其弊端是操作強耦合維護代價高。 JavaScript環(huán)境中產(chǎn)生異步操作的函數(shù)分為兩大類:計時函數(shù)和I/O函數(shù)。如果要在應用中定義復雜的異步操作,就要使用者兩類異步函數(shù)作為基本的構造快。本文沒有對某個知識點...

    Travis 評論0 收藏0
  • ES6 異步編程之一:Generator

    摘要:生成器是原生提供的異步編程方案,其語法行為和傳統(tǒng)函數(shù)完全不同,阮大的入門一書中對生成器有比較詳盡的介紹,還有一些其他的文章可以參考,比如入門深入淺出三生成器深入淺出十一生成器,續(xù)篇本文主要是通過一些代碼示例來記錄和總結生成器的用法。 Generator 生成器是es6原生提供的異步編程方案,其語法行為和傳統(tǒng)函數(shù)完全不同,阮大的《ECMAScript 6 入門》一書中對生成器有比較詳盡的...

    Eidesen 評論0 收藏0
  • ES6中的異步編程Generators函數(shù)+Promise:最強大的異步處理方式

    摘要:更好的異步編程上面的方法可以適用于那些比較簡單的異步工作流程。小結的組合目前是最強大,也是最優(yōu)雅的異步流程管理編程方式。 訪問原文地址 generators主要作用就是提供了一種,單線程的,很像同步方法的編程風格,方便你把異步實現(xiàn)的那些細節(jié)藏在別處。這讓我們可以用一種很自然的方式書寫我們代碼中的流程和狀態(tài)邏輯,不再需要去遵循那些奇怪的異步編程風格。 換句話說,通過將我們generato...

    Taonce 評論0 收藏0

發(fā)表評論

0條評論

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