您的位置:首页 > 其它

【ES6】Generators的原理

2017-01-07 10:50 381 查看
https://davidwalsh.name/es6-generators

在ES6中最有趣的特点之一就是一个崭新的方法类型,叫做generator(发电机?)。这个名字有点儿奇怪,但是乍看之下,它的操作可能会非常陌生。本文的目的一是为了解释它运作的原理,二是帮助读者建立理解为什么他们对JS的未来有很强的作用力。

运行到终点

当我们讨论关于Generator时第一件需要注意的事情就是,它们与正常方法在“运行到完成”的期望值上有什么不同。

无论你是否意识到,你总是能够对你的方法假设一些基本的事情:一旦功能开始运行,在别的JS代码开始运行时,它总会一直运行直到完成。

举个例子:

setTimeout(function(){
console.log("Hello World");},1);
function foo() {
// NOTE: don't ever do crazy long-running loops like this
for (var i=0; i<=1E10; i++) {
console.log(i);
}}
foo();// 0..1E10// "Hello World"


这里,for循环会占用相当长的时间,不止一毫秒,去执行,但是我们返回调用console.log的语句却不能在foo()方法运行的时候打断它,所以它在循环事件(loop)后面卡住了,并且非常耐心的等待运行。

但是,如果foo()可以被打断呢?这样会不会毁了我们的工程呢?

那确实是多线程编码的 噩梦 挑战,但是我们非常幸运是在JS里而不用担心这样的事情,因为JS总是单线程(在任何给定的时间里,只有一个命令或者方法会执行)。



注释:web
worker是一个你可以为了JS项目的一部分去运行而运转一整个分离的线程的机制,它和你主要的JS项目线程是并行的。它不会将多线程的复杂引入我们的项目的理由就是这两个线程只能通过正常的异步事件交流,这种行为遵守了循环事件每次一个的行为并且被运行到完成所需要。

运行...停止...运行

有了ES6的“发电机”,我们就可以拥有一种完全不同的方法,它可以在运行过程中被暂停一次或多次,并稍后可以恢复;而且还允许其他的代码在它暂停的时间里去运行。

如果你以前读过关于并发或多线程编程的任何文章,你可能已经看过“合作”这个术语了,它表明了一个过程(在我们的例子里,就是一个方法),它本身允许中断的时候可以选择,以便它可以和别的代码合作。

这个概念的对比是“先发制人”(???译者自己也没明白,原词是preemptive),这个暗示了一种过程或者是方法可能会被打断。

ES6的“发电机”功能在他们的并发行为上是合作的。而在这个方法的身体里,你可以使用新的yield关键字来从它的内部暂停这个方法。没有什么可以从“发电机”外部去暂停它;当它遇到一个yield的时候它就会从内部暂停它自己。

然而,一旦一个“发电机”用yield去暂停它自己,它也无法靠自己去恢复。必须用外部控件去重新启动“发电机”。我们将解释这在一瞬间是如何发生的。

因此,基本上,一个“发电机”函数可以和你选择的次数一样多的去停止并且重新启动。事实上,你也可以制定一个无限循环的“发电机”方法(比如臭名昭著的while (true) { .. }),它实际上从来没有停过。而这通常很疯狂或者又只是普通JS程序的一个错误,

相关link
https://link.zhihu.com/?target=http%3A//davidwalsh.name/es6-generators-dive https://link.zhihu.com/?target=http%3A//davidwalsh.name/async-generators https://link.zhihu.com/?target=http%3A//davidwalsh.name/concurrent-generators
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: