inv*_*ess 5 javascript ecmascript-6
我花了几天的时间来了解ES6版本中引入的JavaScript中的Generator函数。
发电机的地方有很多,但对我来说似乎很有趣的是,到处都有
生成器函数是一种同步编写异步代码的方法。
我要提出的问题是“为什么仅出于此目的就需要引入一种完全不同的编程策略?”
我了解JS代码的异步特性使新手很难理解和调试代码,但是是否需要彻底改变编码风格?
我可能错了或者没有完全理解其引入背后的概念,但是对所有事物的好奇心促使我提出这个问题。
因为闭包对于简单迭代不太方便;即使语言之前支持相同的模式,简化相当常见的任务的语法也是值得的。比较一下:
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
}
Run Code Online (Sandbox Code Playgroud)
到:
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
}
Run Code Online (Sandbox Code Playgroud)
当然,代码行数的节省并不令人难以置信。它主要只是减少样板文件和不必要的名称,消除了处理简单情况的闭包的需要,并通过语法for...of提供了一种通用机制来迭代任意可迭代的事物,而不是要求用户显式构造初始闭包并通过以下方式推进它:姓名。但如果该模式足够常见,那就足够有用了。
正如评论中所指出的,a, b, c必须Array类似于基于闭包的方法(或者您会使用不同的基于闭包的方法,其中编写者对chain传递给它的东西强加任意要求,特殊情况下是Array类似的东西与类似生成器的东西闭包)并且处理是破坏性的(您需要添加更多闭包状态或制作副本以使其非破坏性,从而使其更复杂或更慢);对于基于生成器的方法yield*,不需要特殊情况。这使得生成器无需复杂的规格即可组合;他们可以轻松地相互构建。
| 归档时间: |
|
| 查看次数: |
336 次 |
| 最近记录: |