1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-28 21:32:20 +00:00

修改Readme和generator

This commit is contained in:
Ruan Yifeng 2014-12-30 09:29:50 +08:00
parent 38adc8e8eb
commit 2556bf8962
2 changed files with 22 additions and 17 deletions

View File

@ -8,7 +8,7 @@
本书为中级难度适合已有一定JavaScript语言基础的读者用来了解这门语言的最新发展也可当作参考手册查寻新增的语法点。
全书已由电子工业出版社出版([版权页](images/copyright.png)[内页1](images/page1.png)[内页2](images/page2.png)),铜版纸全彩印刷,附有索引。电子版与纸版的内容是一致的,如果您对本书感兴趣,建议考虑购买纸版。这样可以使出版社不因出版开源书籍而亏钱,进而鼓励更多的作者开源自己的书籍。
全书已由电子工业出版社出版([版权页](images/copyright.png)[内页1](images/page1.png)[内页2](images/page2.png)),铜版纸全彩印刷,附有索引。纸版是根据电子版排印的内容截止到2014年10月感谢张春雨编辑支持我将全书开源的做法。如果您对本书感兴趣,建议考虑购买纸版。这样可以使出版社不因出版开源书籍而亏钱,进而鼓励更多的作者开源自己的书籍。
- [京东](http://item.jd.com/11526272.html)
- [当当](http://product.dangdang.com/23546442.html)

View File

@ -1,6 +1,8 @@
# Generator 函数
## 含义
## 语法
### 简介
所谓Generator有多种理解角度。首先可以把它理解成一个内部状态的遍历器每调用一次内部状态发生一次改变可以理解成发生某些事件。ES6引入Generator函数作用就是可以完全控制内部状态的变化依次遍历这些状态。
@ -72,7 +74,7 @@ setTimeout(function () {
上面代码中函数f如果是普通函数在为变量generator赋值时就会执行。但是函数f是一个Generator函数就变成只有调用next方法时函数f才会执行。
## next方法的参数
### next方法的参数
yield语句本身没有返回值或者说总是返回undefined。next方法可以带一个参数该参数就会被当作上一个yield语句的返回值。
@ -120,7 +122,7 @@ it.next(13)
注意由于next方法的参数表示上一个yield语句的返回值所以第一次使用next方法时不能带有参数。V8引擎直接忽略第一次使用next方法时的参数只有从第二次使用next方法开始参数才是有效的。
## for...of循环
### for...of循环
for...of循环可以自动遍历Generator函数且此时不再需要调用next方法。
@ -165,7 +167,7 @@ for (let n of fibonacci()) {
从上面代码可见使用for...of语句时不需要使用next方法。
## throw方法
### throw方法
Generator函数还有一个特点它可以在函数体外抛出错误然后在函数体内捕获。
@ -245,7 +247,7 @@ function* g(){
```
## yield*语句
### yield*语句
如果yield命令后面跟的是一个遍历器需要在yield命令后面加上星号表明它返回的是一个遍历器。这被称为yield*语句。
@ -357,7 +359,7 @@ result
```
## 作为对象属性的Generator函数
### 作为对象属性的Generator函数
如果一个对象的属性是Generator函数可以简写成下面的形式。
@ -383,7 +385,9 @@ let obj = {
```
## Generator与状态机
## 含义
### Generator与状态机
Generator是实现状态机的最佳结构。比如下面的clock函数就是一个状态机。
@ -417,6 +421,16 @@ var clock = function*(_) {
上面的Generator实现与ES5实现对比可以看到少了用来保存状态的外部变量ticking这样就更简洁更安全状态不会被非法篡改、更符合函数式编程的思想在写法上也更优雅。Generator之所以可以不用外部变量保存状态是因为它本身就包含了一个状态信息即目前是否处于暂停态。
### Generator与协程
协程coroutine是一种程序运行的方式。传统的“子例程”subroutine采用堆栈式“后进先出”的执行方式只有当调用的子函数完全执行完毕才会结束执行父函数。协程与其不同多个函数可以并行执行但是只有一个函数处于正在运行的状态其他函数都处于暂停态suspended函数之间可以交换执行权。也就是说一个函数执行到一半可以暂停执行将执行权交给另一个函数等到稍后收回执行权的时候再恢复执行。这种可以并行执行、交换执行权的函数就称为协程。
不难看出,协程适合用于多任务运行的环境。在这个意义上,它与线程很相似,都有自己的执行上下文、可以分享全局变量。它们的不同之处在于,同一时间可以有多个线程处于运行状态,但是运行的协程只能有一个,其他都处于暂停状态。此外,线程是抢先式的,到底哪个线程优先得到资源,必须由运行环境决定,但是协程是合作式的,执行权由协程自己分配。
Generator函数是ECMAScript 6对协程的实现但属于不完全实现只做到了暂停执行和转移执行权有一些特性没有实现比如不支持所调用的函数之中的yield语句。
如果将Generator函数看作多任务运行的方式存在多个进入点和退出点。那么一方面并发的多任务可以写成多个Generator函数另一方面继发的任务则可以按照发生顺序写在一个Generator函数之中然后用一个任务管理函数执行参考本节的“控制流管理”部分
## 应用
Generator可以暂停函数执行返回任意表达式的值。这种特点使得Generator有多种应用场景。
@ -661,12 +675,3 @@ function doStuff() {
上面的函数可以用一模一样的for...of循环处理两相一比较就不难看出Generator使得数据或者操作具备了类似数组的接口。
## Generator与协程
协程coroutine是一种程序运行的方式。传统的“子例程”subroutine采用堆栈式“后进先出”的执行方式只有当调用的子函数完全执行完毕才会结束执行父函数。协程与其不同多个函数可以并行执行但是只有一个函数处于正在运行的状态其他函数都处于暂停态suspended函数之间可以交换执行权。也就是说一个函数执行到一半可以暂停执行将执行权交给另一个函数等到稍后收回执行权的时候再恢复执行。这种可以并行执行、交换执行权的函数就称为协程。
不难看出,协程适合用于多任务运行的环境。在这个意义上,它与线程很相似,都有自己的执行上下文、可以分享全局变量。它们的不同之处在于,同一时间可以有多个线程处于运行状态,但是运行的协程只能有一个,其他都处于暂停状态。此外,线程是抢先式的,到底哪个线程优先得到资源,必须由运行环境决定,但是协程是合作式的,执行权由协程自己分配。
Generator函数是ECMAScript 6对协程的实现但属于不完全实现只做到了暂停执行和转移执行权有一些特性没有实现比如不支持所调用的函数之中的yield语句。
如果将Generator函数看作多任务运行的方式存在多个进入点和退出点。那么一方面并发的多任务可以写成多个Generator函数另一方面继发的任务则可以按照发生顺序写在一个Generator函数之中然后用一个任务管理函数执行参考本节的“控制流管理”部分