Generator速成大法!!!码住😡

109 阅读3分钟

Generator是什么?

Generator 函数是 ES6 提供的一种异步编程解决方案。

官方描述:

1、Generator 对象由生成器函数返回并且它符合可迭代协议迭代器协议

2、生成器函数在执行时能暂停,后面又能从暂停处继续执行;

第一句话告诉我们 Generator 对象不能够通过构造函数那样new出来,而是由生成器函数生成,并且可以用 for... of... 进行遍历; 第二句话的意思是 生成器函数 内的代码需要特定的方式执行,而且在执行过程中可以停住,更可以继续执行。

结合代码来理解官方描述:

// 1.生成器函数的基本写法:functon关键字后面加*号,代表这是一个生成器函数
// 2.在生成器函数内部通过 yield 关键字暂停代码的执行 
function* func() {
  yield 'study'
  yield 'Generator'
  yield 'function'
}

// 3.调用生成器函数 ,返回一个 Generator 对象 f
// (⚠️注意:此时调用func函数时,它内部的代码不会执行)
const f = func()

//4.调用 Generator 对象的 next() 方法,func 内部代码会自上而下执行,遇到第 yield 关键字时暂停执行,并且返回 yield 后面的表达式
f.next() //{value: 'study', done: false}

使用for... of...遍历 Generator 对象 f

for (const iterator of f) {
  console.log(iterator)
}

输出结果: image.png

Generator 的详细案例演示

Generator-核心语法

  1. 如何定义生成器函数:
  2. 如何获取generator对象
  3. yield表达式的使用
  4. 通过for... of...获取每一个yield的值
// 1. 通过function* 创建生成器函数 
function* foo() {
  // 遇到yield表达式时会暂停后续的操作
  yield 'a'
  yield 'b'
  yield 'c'
  return 'd'
}
// 2. 调用函数获取生成器
const f = foo()
// 3. 通过next方法获取 yield 之后的表达式结果,会被包装到一个对象中
// 执行一次next 即可获取一次 yield之后的表达式结果
const res1 = f.next()
console.log(res1)// {value: 'a', done: false}
const res2 = f.next()
console.log(res2)// {value: 'b', done: false}
const res3 = f.next()
console.log(res3)// {value: 'c', done: false}
// 最后一次可以拿到return的结果
const res4 = f.next()
console.log(res4)// {value: 'd', done: true} 
// done 为true之后,获取到的value为undefined
const res5 = f.next()
console.log(res5)// {value: undefined, done: true} 


// 4. 通过for of 获取每一个yield之后的值,
const f2 = foo()
for (const iterator of f2) {
  console.log(iterator)
}

输出结果: image.png

Generator-id生成器

需求: 使用Generator实现一个id生成器

思路:

  1. 定义生成器函数
  2. 内部使用循环,通过yield返回id并累加
// 1. 通过function* 创建生成器函数 
function* generatorId() {
  let id = 0
  // 无限循环
  while (true) {
    // id累加并返回
    yield id++
  }
}
// 2. 调用函数获取生成器
const idMaker = generatorId()
// 3. 需要id的时候 通过next获取即可
const { value: id1 } = idMaker.next()
console.log(id1)
const { value: id2 } = idMaker.next()
console.log(id2)

输出结果: image.png 生成器函数内部的代码会在调用next方法时执行,利用这一特点,可以实现任意的生成器,需要时调用next即可获取结果。

总结

学习 Generator 的核心思路记住以下两点:

  1. 可以通过生成器函数(function* xxx(){})来生成Generator对象;
  2. 通过Generator对象的next方法可以获取yield表达式之后的结果;