TL;DR:生成器的本质是控制代码执行的暂停。
对于生成器本身,您可以参考this http://wiki.ecmascript.org/doku.php?id=harmony%3agenerators.
总而言之,您应该区分三个组件:
1. 生成器功能
2. 发电机
3. 生成结果
生成器函数很简单function
头上有星星并且(可选)yield
在它的身体里。
function *generator() {
console.log('Start!');
var i = 0;
while (true) {
if (i < 3)
yield i++;
}
}
var gen = generator();
// nothing happens here!!
生成器函数本身不执行任何操作,只是返回一个生成器,在上面的情况下,gen
。
这里没有控制台输出,因为只有在返回之后发电机's next
方法被称为主体生成器函数会跑。
Generator 有几个方法,其中最重要的一个是next
. next
运行代码并返回生成器结果.
var ret = gen.next();
// Start!
console.log(ret);
// {value: 0, done: false}
ret
上面是生成器结果。它有两个属性:value
,你产生的价值生成器函数, and done
,一个标志,指示是否生成器函数 return.
console.log(gen.next());
// {value: 1, done: false}
console.log(gen.next());
// {value: 2, done: false}
console.log(gen.next());
// {value: undefined, done: true}
此时,没有人会指望你了解generator,至少不会期望你了解generator的异步电源。
简单来说,generator有两个特点:
- 我们可以选择跳出函数并让外部代码决定何时跳回函数。
- 异步调用的控制可以在代码之外完成
在代码中,yield
跳转到函数之外,并且next(val)
跳回函数并将值传递回函数。
外部代码可以处理异步调用并决定切换到您自己的代码的适当时间。
再看一下示例:
var gen = generator();
console.log('generated generator');
console.log(gen.next().value);
// mock long long processing
setTimeout(function() {
console.log(gen.next().value);
console.log('Execute after timer fire');
}, 1000);
console.log('Execute after timer set');
/* result:
generated generator
start
0
Execute after timer set
1
Execute after timer fire
*/
看?生成器函数本身不处理回调。外部代码确实如此。
基地就在这里。您可以详细说明此代码以支持完全异步性,同时保持生成器功能如同步功能。
例如,假设geturl
是一个异步调用,返回一个promise
目的。你可以写var html = yield getUrl('www.stackoverflow.com');
这会跳转到您的代码之外。外部代码会执行以下操作:
var ret = gen.next();
ret.then(function (fetchedHTML) {
// jumps back to your generator function
// and assign fetchHTML to html in your code
gen.next(fetchedHTML);
});
更完整的指南,请参阅this http://blogs.atlassian.com/2013/11/harmony-generators-and-promises-for-node-js-async-fun-and-profit/。
和存储库一样co https://github.com/visionmedia/co, galaxy https://github.com/bjouhier/galaxy, suspend https://github.com/jmar777/suspend等等。