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。