參考鏈接:http://www.ruanyifeng.com/blog/2015/04/generator.html 阮一峰先生的一篇日志
function* gen(x){
var y = yield x + 2;
return y;
}
var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true}
上面代碼中隘谣,調(diào)用 Generator 函數(shù),會返回一個內(nèi)部指針(即遍歷器)g 篷扩。這是 Generator 函數(shù)不同于普通函數(shù)的另一個地方稠氮,即執(zhí)行它不會返回結(jié)果曹阔,返回的是指針對象。調(diào)用指針 g 的 next 方法隔披,會移動內(nèi)部指針(即執(zhí)行異步任務(wù)的第一段)赃份,指向第一個遇到的 yield 語句,上例是執(zhí)行到 x + 2 為止锹锰。
換言之芥炭,next 方法的作用是分階段執(zhí)行 Generator 函數(shù)。每次調(diào)用 next 方法恃慧,會返回一個對象园蝠,表示當(dāng)前階段的信息( value 屬性和 done 屬性)。value 屬性是 yield 語句后面表達(dá)式的值痢士,表示當(dāng)前階段的值彪薛;done 屬性是一個布爾值,表示 Generator 函數(shù)是否執(zhí)行完畢怠蹂,即是否還有下一個階段善延。
http://www.html-js.com/article/1711 yield 原理篇
如下示例代碼,在瀏覽器中打斷點(diǎn)可以一窺 yield 執(zhí)行方法
function* fib2(){
yield 0;//狀態(tài)0城侧,第一次調(diào)用next易遣,返回0,并改變狀態(tài)
yield 1;//狀態(tài)1嫌佑,第二次調(diào)用next豆茫,返回1,并改變狀態(tài)
var p1 = 0
,p2 =1
,cur = p1+p2;
while(true){
yield cur;//狀態(tài)2屋摇,后面調(diào)用next揩魂,返回相應(yīng)的幾個,狀態(tài)不在改變
p1 = p2;
p2 = cur;
cur = p1+p2;
}
}
var fibIter2 = fib2();
for(var i =0;i<8;i++){
console.log(fibIter2.next().value);
}
進(jìn)階示例
示例1:
function* gen(x){
var y = yield x + 2;
return y;
}
var g = gen(1);
console.log(g.next()) // { value: 3, done: false }
console.log(g.next()) //{ value: undefined, done: true}
console.log(g.next()) // { value: undefined, done: true}
示例2:
//Iterator 遍歷
//Generator(生成器)是ES6標(biāo)準(zhǔn)引入的新的數(shù)據(jù)類型炮温。一個generator看上去像一個函數(shù)火脉,但可以返回多次
//1.類似于將異步變成同步,使函數(shù)可以按順序依次執(zhí)行,用的已經(jīng)不多了倦挂,有新的東西替代了
let xiaochuan = function*(){
yield "冰淇淋";
yield "漢堡";
}
// console.log(xiaochuan().next());//Object {value: "冰淇淋", done: false}
const result = xiaochuan();
console.log(result.next());//Object {value: "冰淇淋", done: false}
console.log(result.next());//Object {value: "漢堡", done: false}
console.log(result.next());//Object {value: undefined, done: true}
總結(jié):yield 執(zhí)機(jī)制是這樣的:yield 返回的是一個指針對象 .next() 執(zhí)行 -> 發(fā)現(xiàn) yeild 語句執(zhí)行后返回畸颅,返回的值便是當(dāng)時這個階段 后面表達(dá)式的值,直到執(zhí)行完畢 done:true 為止妒峦。
擴(kuò)展出如下的示例:
http://www.ruanyifeng.com/blog/2015/05/async.html async 函數(shù)的含義和用法(阮一峰先生的日志)
前文有一個 Generator 函數(shù)重斑,依次讀取兩個文件兵睛。
var fs = require('fs');
var readFile = function (fileName){
return new Promise(function (resolve, reject){
fs.readFile(fileName, function(error, data){
if (error) reject(error);
resolve(data);
});
});
};
var gen = function* (){
var f1 = yield readFile('/etc/fstab');
var f2 = yield readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
寫成 async 函數(shù)肯骇,就是下面這樣。
var asyncReadFile = async function (){
var f1 = await readFile('/etc/fstab');
var f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};