## Generator
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态。
```
function* gen() {
yield 'one'
yield 'two'
yield 'three'
}
g = gen()
let a = g.next()
let b = g.next()
let c = g.next()
let d = g.next()
console.log([a, b, c, d])
// 0: {value: "one", done: false}
// 1: {value: "two", done: false}
// 2: {value: "three", done: false}
// 3: {value: undefined, done: true}
```
使用 next 方法,可以访问 生成器 的下一个状态,包括 value 和 done,分别表示 当前状态 的值 和 是否还有下一个值。
### for-of 遍历
我们甚至可以使用 for-of 循环遍历输出 生成器的所有状态值
```
function* gen() {
yield 'one'
yield 'two'
yield 'three'
}
g = gen()
for (let i of g) {
console.log(i)
}
```
或者
```
function* gen() {
yield 'one'
yield 'two'
yield 'three'
}
for (let i of gen()) {
console.log(i)
}
```
输出
```
one
two
three
```
### 与异步函数结合
使用 Generator 函数管理流程,遇到异步操作的时候,通常返回一个Promise对象。
```
const g = function* () {
yield Promise.resolve('foo');
yield Promise.resolve('bar');
yield Promise.resolve('baz');
}
function run (generator) {
const it = generator();
function next (result) {
if (result.done) {
return result.value;
}
return result.value.then(value => {
console.log(value)
return next(it.next());
});
}
next(it.next());
}
run(g);
```