声明 Generator 函数
Generator 函数, 又称生成器函数, 是 ES6 的一个重要的新特性.
- // 声明一个 Hello 的 Generator 函数
- function* Hello(name) {
- yield `hello ${name}`;
- yield `how are you`;
- yield `bye`;
- }
注意:
1, 普通函数用 function 来声明, Generator 函数用 function * 声明.
2,Generator 函数内部有新的关键字: yield, 普通函数没有.
调用 Generator 函数
- // 声明一个 Hello 的 Generator 函数
- function* Hello(name) {
- yield `hello ${name}`;
- yield `how are you`;
- yield `bye`;
- }
- // 调用 Hello 函数
- let ite = Hello('王德发');
- // 结果:[object Generator]
- ite.next();
- //{value: "hello 王德发", done: false}
- ite.next();
- //{value: "how are you", done: false}
- ite.next();
- //{value: "bye", done: false}
- ite.next();
- //{value: undefined, done: true}
函数执行后, 返回了一个:[object Genrator]生成器对象, 我们把它赋值到变量 ite 中, 仅此而已, 并没有做太多的事情.
第 1 次调用生成器对象 ite 的 next( )方法, 返回了一个对象:
{value: "hello 王德发", done: false}
第 2 次调用生成器对象 ite 的 next( )方法, 同样得到了一个对象:
{value: "how are you", done: false}
第 3 次调用生成器对象 ite 的 next( )方法, 又得到了一个对象:
{value: "bye", done: false}
第 4 次调用生成器对象 ite 的 next( )方法, 返回的对象:
{value: undefined, done: true}
Generator 函数的行为
Generator 函数被调用后并不会一直执行到最后, 它是先回返回一个生成器对象, 然后 hold 住不动, 等到生成器对象的 next( )方法被调用后, 函数才会继续执行, 直到遇到关键字 yield 后, 又会停止执行, 并返回一个 Object 对象, 然后继续等待, 直到 next( )再一次被调用的时候, 才会继续接着往下执行, 直到 done 的值为 true.
yield 语句的作用
而 yield 在这里起到了十分重要的作用, 就相当于暂停执行并且返回信息. 有点像传统函数的 return 的作用, 但不同的是普通函数只能 return 一次, 但是 Generator 函数可以有很多个 yield. 而 return 代表的是终止执行, yield 代表的是暂停执行, 后续通过调用生成器的 next( )方法, 可以恢复执行.
next( )方法接收参数
next( )方法还可以接受一个参数, 它的参数会作为上一个 yield 的返回值, 我们来看一下:
- // 声明一个 Hello 的 Generator 函数
- function* Hello() {
- let res = yield `hello`;
- yield res;
- }
- let iterator = Hello();
- // 结果: 一个生成器对象
- iterator.next();
- // 结果:{value: "hello", done: false}
- iterator.next("王德发");
- // 结果:{value: "王德发", done: false}
注意函数体内的第一个 yield 关键字, 我们把它的返回值赋值给了一个变量 res.
再看 2 次 next 方法的调用:
第 1 次调用 next( )方法, 返回的对象属性 value 值为 "hello", 属性 done 值为: fasle, 并暂停执行.
第 2 次 next( )方法, 传入参数: 字符串 "王德发". 此时, 第二个 yield 关键字紧跟着的是变量 res, 而变量 res 的值正是上一个关键字 yield 的返回值. 也就是说这个值正是我们传入的参数:"王德发". 因为: next( )的参数会作为上一个 yield 的返回值.
关键字 yield*
在一个 Generator 函数里面, 如果我们想调用另一个 Generator 函数, 就需要用到的关键字是: yield*.
- // 声明 Generator 函数: gen1
- function* gen1() {
- yield "gen1 start";
- yield "gen1 end";
- }
- // 声明 Generator 函数: gen2
- function* gen2() {
- yield "gen2 start";
- yield "gen2 end";
- }
- // 声明 Generator 函数: start
- function* start() {
- yield "start";
- yield* gen1();
- yield* gen2();
- yield "end";
- }
- // 调用 start 函数
- var ite = start();
- // 创建一个生成器
- ite.next();
- //{value: "start", done: false}
- ite.next();
- //{value: "gen1 start", done: false}
- ite.next();
- //{value: "gen1 end", done: false}
- ite.next();
- //{value: "gen2 start", done: false}
- ite.next();
- //{value: "gen2 end", done: false}
- ite.next();
- //{value: "end", done: false}
我们主要看 start( )这个 Generator 函数, 其中有两句代码:
- yield* gen1();
- yield* gen2();
如果一个 Generator 函数 A 执行过程中, 进入 (调用) 了另一个 Generator 函数 B, 那么会一直等到 Generator 函数 B 全部执行完毕后, 才会返回 Generator 函数 A 继续执行.
Generator 函数的用途
它可以控制函数的内部状态, 依次遍历每个状态; 可以根据需要, 轻松地让函数暂停执行或者继续执行. 利用 Generator 函数暂停执行的作用, 可以将异步操作的语句写到 yield 后面, 通过执行 next 方法进行回调.
来源: http://www.jianshu.com/p/876aea4cc12f