JavaScript-生成器

80 阅读2分钟

什么是生成器?

生成器是用于函数控制、使用的方案,可以让我们灵活的控制函数的继续执行、暂停执行

生成器函数

  • 生成器函数需要在function后面加一个*号
  • 生成器函数可以通过yield关键字来控制函数的执行
  • 生成器函数默认返回值是一个生成器对象(Generator)
    • 生成器是一个特殊的迭代器
    • 想要执行生成器函数内部的代码,需要调用返回的生成器对象中的next方法
    • 生成器函数在执行的时候碰到yield关键字会暂停执行
// 生成器函数
function* foo() {
  console.log('一')
  console.log('二')
  yield // 生成器函数执行遇到yield关键字会暂停执行,需要再次调用next方法执行下面的代码
  console.log('三')
  console.log('四')
  yield
  console.log('五')
  console.log('六')
}

// 执行生成器函数默认会返回一个生成器
const generator = foo()
// 调用生成器的next方法,让生成器函数中的代码执行
generator.next() 
generator.next()
generator.next()

生成器函数的返回值

// 生成器函数
function* foo() {
  console.log('一')
  console.log('二')
  yield '返回值一' // 可以通过在yield关键字返回结果
  console.log('三')
  console.log('四')
  yield '返回值二'
  console.log('五')
  console.log('六')
}

// 执行生成器函数默认会返回一个生成器
const generator = foo()
// 调用生成器的next方法,让生成器函数中的代码执行
generator.next() // { done 'false' value: '返回值一' }
generator.next() // { done 'false' value: '返回值二' }
generator.next() // { done 'true' value: undefined }

生成器函数传递参数

// 生成器函数
function* foo(value1) { // 一般第一个参数通过函数参数的形式传参
  console.log('一', value1)
  console.log('二', value1)
  // 因为在执行第二个next方法时候,是从这个yield关键字开始执行,所以在这接收到传递的参数
  const value2 = yield // 接收到第二次调用next方法传递的参数
  console.log('三', value2)
  console.log('四', value2)
  const value3 = yield // 接收到第三次调用next方法传递的参数
  console.log('五', value3)
  console.log('六', value3)
}

const generator = foo('我是value1') // 一般第一个参数通过函数参数的形式传参
generator.next()
generator.next('我是value2') // 调用第二次next方法时候传递参数
generator.next('我是value3') // 调用第三次next方法时候传递参数

yield*

yield是yield的一种语法糖,必须在生成器函数中使用,yield可以用来迭代可迭代对象,依次其中一个值。

const names = ['name1', 'name2', 'name3', 'name4']

// 未使用 yield* 语法糖时 需要自己编写
function createArrIterator(arr) {
  for (let i = 0; i < arr.length; i++) {
    yield arr[i]
  }
}

// 使用 yield* 语法糖时 
function createArrIterator(arr) {
    yield* arr // yield* 后面的值为 你要迭代的对象(可迭代对象)
}


const namesIterator = createArrIterator(names)
namesIterator.next()
namesIterator.next()
namesIterator.next()
namesIterator.next()