成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

JiaXinYi / 2950人閱讀

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

前言

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

作為函數(shù)的Generator

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

    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是個(gè)異步調(diào)用,以上的代碼想要能夠執(zhí)行則需要get函數(shù)執(zhí)行得到結(jié)果后調(diào)用生成器的next方法來(lái)推進(jìn),這要求get函數(shù)能持有生成器對(duì)象,這顯然并不容易。

偏函數(shù)

偏函數(shù)(Partial Function)是對(duì)函數(shù)定義域的子集定義的函數(shù),形式上就是指定任意部分參數(shù)生成一個(gè)新的函數(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

一般在設(shè)計(jì)異步調(diào)用api時(shí),我們總是聲明一個(gè)參數(shù)來(lái)接收回調(diào)函數(shù),當(dāng)和偏函數(shù)相結(jié)合就變成這樣:

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

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

生成器和偏函數(shù)

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

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

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

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

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

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

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

    next();
}

run(generator);

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

現(xiàn)在通過(guò)新編寫(xiě)的run函數(shù)就可以來(lái)執(zhí)行本文一開(kāi)始編寫(xiě)的那個(gè)生成器了。

thunkify

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

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

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

第二個(gè)問(wèn)題是本方案的核心機(jī)制所要求,但第一個(gè)問(wèn)題我們可以通過(guò)thunkify來(lái)解決,api依舊按照get(value, callback)方式定義,但定義生成器時(shí)需要將異步api調(diào)用通過(guò)thunkify轉(zhuǎn)換為偏函數(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"));
        }
    }

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/81484.html

相關(guān)文章

  • 談?wù)?em>ES6前后的異步編程

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

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

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

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

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

    Travis 評(píng)論0 收藏0
  • ES6 異步編程之一:Generator

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

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

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

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

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

0條評(píng)論

閱讀需要支付1元查看
<