## 概述
Generator是ES6引入的實現異步操作的一種新方法,在Generator出現之前,不管哪種方法,異步操作都是使用回調函數來實現的。只從出現了Generator之后,開發人員可以使用同步調用的邏輯來實現異步操作,只要在需要等待的地方,使用yield語句放棄運行即可。
### Generator的基本寫法
和學習所有其他語言特性一樣,我們使用一個Hello World來作為Generator的入門代碼
```javascript
function* helloworld(){
yield "Hello";
return "World!";
}
func = helloworld();
func.next();//return { value: 'Hello', done: false }
func.next();//return { value: 'World!', done: true }
func.next();//return { value: '', done: true }
```
從上面的代碼的輸出可以看出
* Generator函數的定義,是通過**function ***實現的
* 對Generator函數的調用返回的實際是一個遍歷器,隨后代碼通過使用遍歷器的next方法來獲得函數的輸出
* 通過使用**yield**語句來中斷Generator函數的運行,并且可以返回一個中間結果
* 每次調用**next**方法,Generator函數將執行到下一個yield語句或者是return語句。下面我們就對上面代碼的每次next調用進行一個詳細的解釋
* 第一次調用next方法的時候,函數執行到```yield "Hello"```語句停了下來,并且返回了Hello這個value,隨同value返回的done屬性表明Generator函數的運行還沒有結束
* 第二次調用next方法的時候,函數執行到```return "World!"```語句停了下來,并且返回了World!這個value,隨同value返回的done屬性表明Generator函數的運行已經結束
* 第三次調用next方法的時候,由于Generator函數執行已經結束了,所以函數調用立即返回,done屬性表明Generator函數已經結束運行,value是空的,因為這次調用并沒有執行任何語句
### yield語句
yield語句在Generator函數的執行過程中扮演了中斷/暫停執行函數的功能。每次你調用next()方法的時候,Generator函數都將執行到下一個yield語句或者return語句,當執行到yield語句的時候,如果yield語句跟著一個表達式,那么表達式的值將作為value被返回。
## next方法參數
由于yield語句只是拋出value, 但是本身并不返回value,如果你要yield語句有返回值,就要在調用next方法的時候,傳入一個參數,這個參數就將作為上一個yield語句的返回值,下面是一個例子
```javascript
function* f() {
for(var i=0; true; i++) {
var reset = yield i;
if(reset) { i = -1; }
}
}
var g = f();
g.next() // { value: 0, done: false }
g.next() // { value: 1, done: false }
g.next(true) // { value: 0, done: false }
```
## for...of循環
在上面的所有例子中,如果我們要讓Generator函數執行下一步,就必須調用一次next方法,那么有沒有什么方法讓Generator函數自動執行每一步而不需要代碼干預呢?答案是肯定的,我們可以使用for...of循環來實現,下面是一個具體的例子。在下面的例子中,for..of loop將遍歷所有的yield語句(**記住只是遍歷yield語句,因此return語句的返回值是不會輸出的**)
```javascript
function* loopThroughInt(){
for (let index = 0; index < 100; index++){
yield index;
}
return 100;
}
for (let v of loopThroughInt()){
console.log(v); //output 0...99
}
```
## yield*
如果在Generator函數內部需要調用另外一個Generator函數,那么對目標函數的調用就需要使用yield*,以下是一個簡單的例子
```javascript
function* objects(){
yield "cat";
yield "dog";
yield "duck";
}
function* say(){
yield* objects();
yield " say hello world!";
}
```
- Introduction
- Nodejs 4.x新特性
- classes
- typed arrays
- generators
- collections
- Set
- Map
- arrow functions
- block scoping
- template strings
- promises
- symbols
- Koa基礎
- 上下文
- koa-generator
- 安裝
- 創建項目
- 更改視圖模板引擎
- Routes
- HTTP
- Get
- 如何獲取query參數
- 如何獲取params
- Post
- 從post獲取參數
- 標準表單(Post with x-www-form-urlencoded)
- 文件上傳(Post with form-data)
- Post with raw
- 數據庫
- MySQL
- Mongo
- 流程控制
- generator/co
- es6的generator是什么?
- co = generator + promise
- async/await
- promise with bluebird
- 測試
- Mocha
- Supertest
- 部署
- 最佳實踐
- FAQ
- 如何發布本書到git pages
- 如何知道require模塊的用法
- koa中的異常處理