Generator
Generator与Promise相同,都是ES6异步编程的解决方案。其实Generator就可以看做一个函数,返回的是一个遍历器对象,而这个返回的遍历器对象可以依次遍历Generator函数内部的每一个状态。
那么Generator与普通函数又有什么区别呢?先给大家看一个generator的例子:
发现什么不同了吗?
1. Generator函数的function比普通函数后面多了一个*
2. Generator函数内部会使用到yield关键字
这个函数是什么意思呢?我们来解读一下,定义了一个helloRabbitGenerator函数,内部有hello、rabbit、lovely三个状态。
Generator函数的调用方式也相似于普通函数,直接在后面加()就可以了。但是也有不同,就是Generator函数即使被调用,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是上一章介绍的遍历器对象(Iterator Object)。
>>>>
next()
我们前面说了,即使Generator函数被调用也不会执行,那么要怎样让函数执行呢,那就要用到next(),通过next来让指针对象移到下一个状态,来执行。比如上面的例子,我们如果想让函数执行就要使用next():第一次调用next执行第一个状态,依次执行后面的状态,直到执行完所有状态,done的状态变为true,再次调用next则不会返回任何数据。
>>>>
yield()
我们前面说了,函数被调用并不会被执行,为什么不会被执行呢,这就是yield的锅了。yield提供了暂停的功能,当遇到yield函数就不能继续执行了。调用了next接着执行下一个,返回yield后面的状态,遇见下一个yield再暂停,以此往复。
>>>>
return()
Generator 函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历 Generator 函数。其实别的没啥特别的,就是一旦调用了return,done的值就会变成true,后面全部都是true,而不会再像以前等到最后一个执行完才变成true。
>>>>
throw()
Generator 函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后在 Generator 函数体内捕获。这里的throw是generator返回对象自己的throw,而非try catch throw的throw。我们借用阮一峰大神的例子看一下吧:在例子中,generator返回的对象i,通过next执行,而后抛出错误。
>>>>
iterator
小伙伴们应该还记得我们上次说了iterator与generator是有关系的,那么关系有在哪里呢?事实上,由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。比如开始的例子,rabbit就是一个遍历器对象,它的Symbol.iterator属性,也是一个遍历器对象生成函数,执行后返回它自己。