生成器

生成器(generator)函数能生成一组值的序列,每个值的生成是基于每次请求,并不是立即生成,必须由我们显示的向生成器请求一个新的值。在结束之前,每当生成器生成一个值后不会停止执行,而是挂起等待下一次请求。

 // 生成器函数,在function后面添加*
function* TestGenerator() { 
  yield 'xingjieStart'
  yield* OtherGenerator()     // 一个生成器将执行权交给另一个生成器 yield后面加*
  yield* NoYieldGenerator()  // 内部没有yield不会生成值,
  yield defaultFunction()        // 普通函数返回函数执行结果
  yield 'xingjieEnd'
}
function* OtherGenerator() {
  yield 'otherStart'
  yield 'otherEnd'
}
function* NoYieldGenerator() {
  return 'have no yield'
}
function defaultFunction() {
  return 'this is defaultFunction'
}

// 迭代器
const testGenerator = TestGenerator()
const testGenerator2 = TestGenerator()

// 调用迭代器的next方法请求一个新的值
const result1 = testGenerator.next()
console.log('result1 : ',  result1)   
// 2个迭代器之间互不干扰(类似构造函数)
const _result1 = testGenerator2 .next()
console.log('_result1 : ',  _result1 )  

// for-of 用来遍历迭代器,在完成前会自动next
for(let item of testGenerator) {
  console.log('item: ', item) 
}

/** logs
  result1 :  {value: "xingjieStart", done: false}
  _result1:  {value: "xingjieStart", done: false}
  item:  otherStart
  item:  otherEnd
  item:  this is defaultFunction
  item:  xingjieEnd
*/

for-of 语法糖

while(!(item = TestGenerator().next()).done) {
   console.log('item: ', item.value)
}

使用生成器生成ID

function* IdGenerator() {
  let id = 0
  while(true) {
    yield ++id
  }
}

const idGenerator = IdGenerator()
for(let i = 0; i < 10; i++) {
  console.log('id: ', idGenerator.next().value)
}

与生成器交互

// 向生成器发送数据
function* TestGenerator() {
 let first = yield '---a----'      // 生成一个值'---a---'的同时会返回一个中间计算结果,通过带参数调用迭代器将参数传回迭代器
 let second = yield first + '----b----'       
 yield first + '----c----' + second 
}

const testGenerator = TestGenerator()
console.log(testGenerator .next().value)           // "---a----"
console.log(testGenerator .next('xj').value)       // "xj----b----"
console.log(testGenerator .next('帅').value)      //  "xj----c----帅"

// 生成器本身也可以带参数
function* TestGenerator2(act) {
 let first = yield act + '---a----'  
 let second = yield act + first + '----b----'
 yield act + first + '----c----' + second
}
const testGenerator2 = TestGenerator2('大喊:')
const _testGenerator2 = TestGenerator2('破音:')

console.log(testGenerator2 .next().value)           // "大喊: ---a----"
console.log(_testGenerator2 .next().value)           // "破音: ---a----"
console.log(testGenerator2 .next('xj').value)       // "大喊: xj----b----"
console.log(_testGenerator2 .next('xj').value)       // "破音: xj----b----"
console.log(testGenerator2 .next('帅').value)      //  "大喊: xj----c----帅"
console.log(_testGenerator2 .next('帅').value)      //  "破音: xj----c----帅"

生成器双向通信:yield从生成器返回值,迭代器的next()方法传入值。
如果没有等待中的yield表达式,则无法传入值,所以第一次调用迭代器的next()方法时如果需要传入值,可以在调用生成器自身时传入参数:TestGenerator2('大喊:')

  • 所有迭代器还有throw方法,可以抛出一个异常
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。