初步学习javascript的generator函数
Posted 西门本不吹雪
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初步学习javascript的generator函数相关的知识,希望对你有一定的参考价值。
ES6提供的Generator语法可以暂停函数的执行,这一点在思考问题上很有帮助。我在考虑问题时常常遇到先执行函数,到某个时刻暂停执行,做一些其他操作后再继续执行函数这样的问题。
当时只是美好的想象,如果函数可以暂停执行就好了。ES6的Generator正是提供这种暂停的机制的。
原打算好好学习一下怎么使用Generator函数的,奈何看了一遍发现有点难度,而且现在正在准备面试,继续深究下去不明智。
既然看了基础的部分就简单记录一下吧,细节及其具体的应用之后再来填坑。
Generator的中文可以解释为生成器。所谓生成器一定是可以生成某一样东西的。JS的生成器Generator是用来生成迭代器的。
也就是说,Generator函数是一种可以返回迭代器的函数。
语法上有2个特征:
- function关键字与函数名之间有一个*
- 函数中使用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方法的运行逻辑:
- 遇到yield语句就暂停执行后面的操作,并将紧根在yield后的表达式的值作为返回的对象的value属性的值。
- 下一次调用next方法时再继续往下执行,直到遇到下一条yield语句。
- 如果没有再遇到新的yield语句,就一直运行到函数结束,直到return 语句为止,并将return语句后面的表达式的值作为返回的对象的value属性的值。
- 如果该函数没有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函数的简单介绍。给函数添加暂停功能有很多实际的应用,后面会逐步介绍。
以上是关于初步学习javascript的generator函数的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript学习笔记(十三)——生成器(generator)