-
Notifications
You must be signed in to change notification settings - Fork 384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ES6 generator 、yield 与co #49
Comments
发现一个很有意思的现象
|
@feibenren 报什么错呢?请提供完整的例子和错误信息,不然没有任何帮助。 |
@youngwind ,是这样的,我照着你的例子本地运行了一下,但是我想实现的效果是,不管传入给delay的时间是多少,我都要立马执行,然后我就把delay函数给修改了一下
这样就会立马执行,全部代码如下:
效果达到了,都会立即执行(当然这样没啥实际意义,直接用最简单的函数也可以实现)
这就不明白什么意思了? |
@feibenren 这现象的确有意思,我并未在官方文档中找到答案,但是下面的这些资料,也许能回答这个问题。 我的理解跟上述资料相同:yield 和 next 必须是交替进行的,也就是说,当 yield 执行还没有结束的时候,是不能执行 next 的。在调用 next 之前,会判断 yield 是否已经 return ,如果没有,则报错。在你举出的例子中,就相当于在 yield 里面调用 next 了。 |
起因
最近在看一些node项目的时候发现里面用到了ES6的generator函数,yield和tj的co库,花了一些时间搞明白它们之间的关系,下面用一些例子说明。
溯源
对于异步的操作,最常规的写法是回调函数,但是深度回调会出现可怕的金字塔。那么,如何用更好的书写方式来避免金字塔,又或者说,怎么样把异步的代码写得看起来好像同步那样子呢?
其中一种解决方案是promise模式,.then一直then下去。ok,从ES6开始,有两个新的特性,叫generator和yield,借助它们,我们能够更优雅地解决这个问题。
generator和yield简介
请看下面的代码
正是这种在单个函数内分步执行性质的引入,使得我们能够通过它来完成异步操作的"优化"。
假设有这样的例子
如何优化这个例子呢?
思路:根据generator的特性,如果我构造一个generator函数包含这三个异步操作,并且把他们各自的callback函数都设置为执行next()函数,这样不就可以实现"看起来是同步"的了吗?
ok。我们已经迈出了一大步了。不过这个写法看着还是有些别扭。
让我们先激动一小会儿,因为你在走tj大神曾经走过的路!
进一步优化这段代码
我们先想想思路,到底有什么办法能够做到呢?最开始的写法之所以会导致金字塔现象,是因为:函数a的执行里面包含执行函数b,所以函数b的执行里面也必须包含执行函数c……如果我们在函数a执行的时候只返回一个function,而这个function接收函数b作为参数。ok,我们先按照这个思路改造一下delay函数和generator函数
我们分析一下:
再次理一下思路,我们应该如何编写//........先略过这一部分的内容呢?
yield特性可以让我们分阶段执行,暂停→开始→暂停→开始……**如果我们可以让第一次执行的结果是一个函数,而这个函数接收第二次执行本身作为cb函数,第二次执行的结果也是一个函数,而这个函数接收第三次执行本身作为cb函数……直到结束。好吧,说再多还不如来几行代码!
嗯,看起来有点绕,多看几遍就好了。
至此,你已经山寨了一个极其简单的co库。
当然tj的co库比这个复杂多了,但是原理就是这样,还可以传参数,支持promise
遗留问题:
参考资料:
The text was updated successfully, but these errors were encountered: