初步学习javascript的generator函数

ES6提供的Generator语法可以暂停函数的执行,这一点在思考问题上很有帮助。我在考虑问题时常常会想如果可以先执行函数,到某个时刻暂停执行,做一些其他操作后再继续执行函数就好了。

当时只是美好的想象,如果函数可以暂停执行就好了。ES6的Generator正是提供这种暂停的机制的。

看了基础的部分就简单记录一下吧,细节及其具体的应用之后再来填坑。

Generator的中文可以解释为生成器。所谓生成器一定是可以生成某一样东西的。JS的生成器Generator是用来生成迭代器的。

也就是说,Generator函数是一种可以返回迭代器的函数。

语法上有2个特征:

  1. function关键字与函数名之间有一个*
  2. 函数中使用yield来定义不同的状态

可以把Generator函数理解成封装了一系列状态的状态机,调用Generator函数会返回一个迭代器对象,这个迭代器对象可以遍历每一个状态。

 

1 function* helloworldGenerator() {
2     console.log('start');
3     console.log(`first state: ${yield '1' + '1'}`);
4     console.log(`second state: ${yield '2' + '2'}`);
5     console.log('end');
6     return 'over';
7 }
8 let hello = helloworldGenerator();

 上面定义了一个generator函数,其中有2个yield语句。需要注意的是,调用迭代器的next方法只会执行yield后面的语句,并把结果作为value返回,并不会执行yield语句所在的整个一行语句。

 
console.log(hello.next());

这里只调用一次next方法,该方法会让Generator函数从函数的开头开始执行,一直到第一个yield语句执行结束。

1 start
2 { value: '11', done: false }

可以看到

  • yield后面语句的值作为迭代器对象的value属性的值
  • 只会执行到yield后面的语句,包含yield的一行语句没有执行。

再调用next方法

1 first state: undefined
2 { value: '22', done: false }

可以看到

  • 从上一个yield语句结束的位置开始执行(输出first state)
  • yield语句的返回值是undefined

再调用next方法

1 second state: undefined
2 end
3 { value: 'over', done: true }

可以看到

  • 从上一个yield语句结束的位置开始执行(输出second state),到return语句结束,return的值作为迭代器对象的value属性的值。

根据上面的测试,我们来整理一下next方法的运行逻辑:

  1. 遇到yield语句就暂停执行后面的操作,并将紧根在yield后的表达式的值作为返回的对象的value属性的值。
  2. 下一次调用next方法时再继续往下执行,直到遇到下一条yield语句。
  3. 如果没有再遇到新的yield语句,就一直运行到函数结束,直到return 语句为止,并将return语句后面的表达式的值作为返回的对象的value属性的值。
  4. 如果该函数没有return语句,则返回对象的value属性的值为undefined

yield语句的返回值

  根据上面的测试,可以看到yield语句的返回值是undefined,Generator函数支持通过给next方法传递参数来作为上一次yield语句的返回值。

还是使用上面的例子,只不过这里调用时给next方法传递了参数。

1 console.log(hello.next());
2 console.log(hello.next('first'));
3 console.log(hello.next('second'));

运行结果

1 start
2 { value: '11', done: false }
3 first state: first
4 { value: '22', done: false }
5 second state: second
6 end
7 { value: 'over', done: true }

可以看到,next方法的参数作为了yield语句的返回值被打印出来了。

第一个yield语句是启动迭代器对象,所以不要带参数,JS会忽略第一个next方法的参数。

 

总结:

上面就是Generator函数的简单介绍。给函数添加暂停功能有很多实际的应用,后面会逐步介绍。

修改:

  1. 2019-02-16 18:26:47 添加说明
posted on 2019-02-09 12:44  西门本不吹雪  阅读(222)  评论(0编辑  收藏  举报