写点什么

重学 JS | 异步编程 Generator()

用户头像
梁龙先森
关注
发布于: 2021 年 01 月 13 日
重学JS | 异步编程  Generator()

Generator()函数是 ES6 的另一种异步编程解决方案。从语法上可以把它理解为一种状态机,内部维护了多个状态,函数执行后会返回一个拥有Iterator接口的对象,通过这个对象可以依次获取Generator()函数内部的每一个状态。


简单用法如下:

function* generator(){	yield 'one'  yield 'two'}
let g = generator() // 获取拥有Iterator接口的对象g.next() // 输出: {value: "one", done: false}g.next() // 输出: {value: "two", done: false}g.next() // 输出: {value: undefined, done: true}
复制代码

从例子可以看出,Generator()函数的特性:

  1. function关键字和函数名之间有一个星号("*")

  2. 内部使用yield关键字来定义内部不同的状态

  3. Generator()函数不是构造函数,默认情况下不能使用new关键字,否则会报错,且内部的 this 也是无效的。

  4. Generator()函数执行后,函数体并没有直接执行,而是返回一个拥有Iterator接口的对象

  5. 调用next()函数才执行Generator()函数的函数体,遇到yield关键字暂停,当然若遇到return语句,则整个函数执行结束,后面的 yield 语句也都失效。

  6. next()函数返回的是一个含有valuedone属性的对象,value表示的是yield表达式执行的结果

  7. 所有yield语句执行完毕时,函数会执行到末尾,如果有return语句,会将return语句的表达式作为value返回,否则返回undefined,同时donetrue,表示遍历结束。


再来看个例子:

function* generator(){	yield 'one'  yield 'two'  return 'three'}let p = generator()for(let key of p){	console.log(key)  // 先后输出 one two}
复制代码

Generator()函数返回的是一个拥有Iterator接口的对象,因此可以用for...of进行遍历,遍历的结果是yield表达式的返回值。


如何让对象类型的值遍历支持for...of呢?通过Generator()函数,看例子:

function* propGenerator(){   let props = Object.keys(this)   for(let p of props){      // 通过yield控制每轮返回的值为属性名和属性值构成的数组      yield [p,this[p]]   }}let obj = {  a:1,  b:2}obj[Symbol.iterator] = propGeneratorfor(let [p,v] of obj){	console.log(p+':'+v)  // 依次输出: a:1  b:2}
复制代码


最后,看看Generator()函数嵌套的问题,可以采用yield* 表达式以支持嵌套使用,看例子:

function* f1(){	yield '1'}function* f2(){	yield '2',  yield* f1()  yield '3'}let f = f2()for(let k of f){	console.log(k)  // 依次输出:2 1 3}
复制代码


至此,我们学习了 ES6 中异步编程的另一个解决方案:Generator()函数。另一个异步编程解决方案Promise点文章链接查看:

异步编程之 Promise


发布于: 2021 年 01 月 13 日阅读数: 26
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论

发布
暂无评论
重学JS | 异步编程  Generator()