Nodejs與ES6系列3:generator對象


3、generator對象

Generator函數是ES6提供的一種異步編程解決方案,語法行為與傳統函數完全不同。Generator的中文翻譯是生成器,它是ECMAScript6(代號harmory)中提供的新特性。在過去,封裝一段運算邏輯的單元是函數。函數只存在“沒有被調用”或者“被調用”的情況,不存在一個函數被執行之后還能暫停的情況,而Generator的出現讓這種情況成為可能。

3.1、generator對象定義

Generator的定義十分簡單,與普通的函數相比,它只多出一個*號。以下為簡單例子:

function *dowork(a) {
    var sum = yield a + 2;
    sum = yield a + 4;
    sum = yield a + 5;
}
var gen = dowork(10);
console.log(gen.next());

======
{ value: 12, done: false }

在dowork函數中通過yield關鍵字讓程序暫停在當前位置,通過generator.next()單步執行,next返回一個對象包括value和done,value為當前程序的計算結果,而done則表示程序是否執行完成。

3.2、generator與異步操作

上一級講了promise對象與異步操作,其實在ES6中也可以用generator來處理異步操作。

function *doWork() {
    var url = 'http://www.163.com';
    var url1 = 'http://www.sina.com';
    var result = yield fetch(url);
    var result1 = yield fetch(url1);
    console.log(result1);
}

var generator = doWork();
var ret = generator.next();
ret.value.then(function (data) {
    var ret1 = generator.next(data);
    ret1.value.then(function (data) {
        generator.next(data);
    })
});

fetch函數是一個異步執行函數,返回promise對象,整個doWork函數由兩個異步函數構成最后打印其中一個異步函數的結果,由於每個next返回的是promise對象因此需要在then中處理數據。

3.3、優化流程

generator實現異步可以讓代碼變得更線性,但是調用過程還是比較麻煩的,因此可以模仿tj大神的co框架(https://github.com/tj/co) 的原理開發一個簡易控制流函數,暫且名字也取為co。

function co(generator) {
    var gen = generator.next();
    var next = function (gen) {
        if (!gen.done) {
            if (gen.value instanceof Promise) {
                gen.value.then(function (data) {
                    next(generator.next(data));
                })
            }
            else {
                next(generator.next(data));
            }
        }
    }
    next(gen);
}
// 執行
co(doWork());

通過co包裝的異步方法可以非常簡單的執行,編程體驗接近與java。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM