我花了几天时间学习了ES6版本中引入的JavaScript函数。
有各种各样的地方发电机被解释,但对我来说似乎太有趣的事实是,据说无处不在
生成器函数是一种同步编写异步代码的方法。
我想提出的问题是"为什么有这么多需要引入完全不同的编程策略?"
我理解JS代码的异步特性使得新手难以理解和调试代码,但它是否需要完全改变编码风格?
我可能错了或者没有完全理解其介绍背后的概念,但是对这一切的好奇是迫使我提出这个问题。
答案 0 :(得分:3)
因为闭包不便于简单迭代;即使语言之前支持相同的模式,简化合理常见任务的语法也是值得的。只是比较:
function chain() {
var args = Array.from(arguments);
return function() {
if (args.length === 0) return undefined; // Or some other sentinel
var nextval = args[0].shift(); // Destructive to avoid copies or more closure vars
if (args[0].length === 0) args.shift();
return nextval;
};
}
var x;
// a, b and c must be indexable, e.g. Arrays; we can't handle other closures without
// requiring some API specific protocol for generation
for (var nextchain = chain(a, b, c); (x = nextchain()) !== undefined;) {
// do stuff with current value
}
为:
function* chain() {
for (var i = 0; i < arguments.length; ++i)
yield* arguments[i];
}
// a, b and c can be any iterable object; yield* can handle
// strings, Arrays, other generators, etc., all with no special handling
for (var x of chain(a, b, c)) {
// do stuff with current value
}
当然,代码行的节省并不令人难以置信。它主要只是减少样板和不必要的名称,无需处理简单情况下的闭包,并使用for...of
语法,提供迭代任意可迭代事物的通用机制,而不是要求用户显式构造初始闭包并按名称推进它。但如果模式足够普遍,那就足够了。
正如评论中所述,a, b, c
必须是Array
- 就像基于闭包的方法一样(或者您使用chain
的作者强加的不同的基于闭包的方法传递给它的东西的任意要求,Array
的特殊情况 - 类似于类似于生成器的闭包)和处理是破坏性的(你需要添加更多的闭包状态或制作副本以使其成为非 - 破坏性,使其更复杂或更慢);对于yield*
的基于生成器的方法,不需要特殊情况。这使得发电机可以在没有复杂规格的情他们可以轻松地相互建立。
答案 1 :(得分:1)
场景1(异步):您可能听说过编写“非阻塞”javascript的重要性。当我们进行I / O操作时,我们在javascript中使用回调或promise来编写非阻塞的javascript代码。
场景2(同步):在javascript中运行无限循环,例如:node -e&#39; while(true){}&#39;可能会冻结你的电脑
考虑到所有这些,ES6生成器允许我们在函数中间有效地“暂停”执行并在将来的某个时间恢复它(同步异步代码)
用例:想象一下,你需要对一系列无限值做一些事情。在这种情况下,数组不会有用,我们可以使用ES6生成器函数
var iterator = generateRandoms(); //suppose it is a generator function which loops through infinite sequence
//generator functions returns a next function which can be called anytime in your code to get the next value from the sequence
console.log(iterator.next()); // { value: 0.4900301224552095, done: false }
console.log(iterator.next()); // { value: 0.8244022422935814, done: false }
就复杂性而言,它是一种新的语法,但不需要很长时间才能掌握它。
进一步阅读: