关于javascript:ES6-系列九Generator

33次阅读

共计 3742 个字符,预计需要花费 10 分钟才能阅读完成。

“Code tailor”,为前端开发者提供技术相干资讯以及系列根底文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。

前言

在开始学习之前,咱们想要告诉您的是,本文章是对阮一峰《ECMAScript6 入门》一书中 “Generator” 章节的总结,如果您已把握上面常识事项,则可跳过此环节间接进入题目练习

  • 什么是 Generator?
  • 如何创立和应用?
  • 如何在异步中利用?
  • 优缺点

如果您对某些局部有些忘记,👇🏻 曾经为您筹备好了!

学习链接

Generator 的学习

Generator 的异步利用

汇总总结

概念

Generator函数是 ES6 中提供的一种 异步编程解决方案 。语法上,首先能够把它了解成,Generator 函数是一个 状态机 ,封装了多个外部状态,须要应用next() 函数 来继续执行上面的代码。

创立和应用

function* helloWorldGenerator() {
  yield 'hello'
  yield 'world'
  return 'ending'
}
var hw = helloWorldGenerator()
hw.next()
// {value: 'hello', done: false}
hw.next()
// {value: 'world', done: false}
hw.next()
// {value: 'ending', done: true}
hw.next()
// {value: undefined, done: true}

罕用办法

  • Generator.prototype.next()

next() 办法返回一个蕴含属性 donevalue 的对象。该办法也能够通过承受一个参数用以向生成器传值

返回的对象蕴含两个属性:

  • done (布尔类型)
  • 如果迭代器超过迭代序列的开端,则值为 true。在这种状况下,value 可选地指定迭代器的返回值。
  • 如果迭代器可能生成序列中的下一个值,则值为 false。这相当于没有齐全指定 done 属性。
  • value – 迭代器返回的任意的 Javascript 值。当 done 的值为 true 时能够疏忽该值。
function* gen() {
  yield 1
  yield 2
  yield 3
}

var g = gen() // "Generator {}"
g.next() // "Object { value: 1, done: false}"
g.next() // "Object { value: 2, done: false}"
g.next() // "Object { value: 3, done: false}"
g.next() // "Object { value: undefined, done: true}"
  • Generator.prototype.return()

return() 办法返回给定的值并完结生成器

function* gen() {
  yield 1
  yield 2
  yield 3
}
var g = gen()
g.next() // { value: 1, done: false}
g.return('foo') // {value: "foo", done: true}
g.next() // { value: undefined, done: true}
  • Generator.prototype.throw()

throw() 办法用来向生成器抛出异样,并复原生成器的执行,返回带有 donevalue 两个属性的对象

  • done (布尔类型)
  • 如果迭代器曾经返回了迭代序列的开端,则值为 true。在这种状况下,能够指定迭代器 value 的返回值。
  • 如果迭代可能持续生产在序列中的下一个值,则值为 false。这相当于不指定 done 属性的值。
  • value – 迭代器返回的任何 JavaScript 值。当 donetrue 的时候能够省略。
function* gen() {while (true) {
    try {yield 42} catch (e) {console.log('Error caught!')
    }
  }
}

var g = gen()
g.next() // { value: 42, done: false}
g.throw(new Error('Something went wrong')) // "Error caught!"

在异步中的利用

var readFile = function (name, ms) {return new Promise((resolve, reject) => {setTimeout(() => {console.log(name + '读完了')
      resolve()}, ms)
  })
}

var gen = function* () {console.log('指定 generator')
  yield readFile('first', 1000)
  yield readFile('second', 2000)
  return '实现了'
}

var g = gen()
var result = g.next()
result.value
  .then(() => {g.next()
  })
  .then(() => {g.next()
  })

优缺点

长处:

  • 能够管制函数的执行,能够配合 co 函数库应用

毛病:

  • 流程治理却不不便(即何时执行第一阶段、何时执行第二阶段)

更多常识请点击 JavaScript 异步发展史

题目自测

一:Generator 函数的 yield 关键字的作用是()?

  • A: 进行执行
  • B: 退出函数
  • C: 暂停执行,期待 next()办法调用
  • D: 进行执行,可自行复原执行

二:如下代码执行后打印后果为()

function* generator(i) {
  yield i
  yield i * 2
}

const gen = generator(10)

console.log(gen.next().value)
console.log(gen.next().value)
  • A: [0, 10], [10, 20]
  • B: 20, 20
  • C: 10, 20
  • D: 0, 10 and 10, 20

三:如下代码执行后打印后果为()

function* generatorOne() {yield ['a', 'b', 'c']
}

function* generatorTwo() {yield* ['a', 'b', 'c']
}

const one = generatorOne()
const two = generatorTwo()

console.log(one.next().value)
console.log(two.next().value)
  • A: a and a
  • B: a and undefined
  • C: ['a', 'b', 'c'] and a
  • D: a and ['a', 'b', 'c']

题目解析

一、

Answer:C

Generator 函数的调用办法与一般函数一样,也是在函数名前面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行后果,而是一个指向外部状态的指针对象,也就是上一章介绍的遍历器对象(Iterator Object)。

下一步,必须调用遍历器对象的 next 办法,使得指针移向下一个状态。也就是说,每次调用 next 办法,外部指针就从函数头部或上一次停下来的中央开始执行,直到遇到下一个 yield 表达式(或 return 语句)为止。换言之,Generator 函数是分段执行的,yield 表达式是暂停执行的标记,而 next 办法能够复原执行。


二、

Answer:C

惯例函数不能在调用后中途进行。然而,生成器函数能够中途“进行”,而后从进行的中央持续。每次生成器函数遇到 yield 关键字时,该函数都会生成它前面指定的值。留神,在这种状况下,生成器函数不返回值,而是生成值。

首先,咱们初始化生成函数,使 i 等于 10。咱们应用 next() 办法调用生成器函数。第一次调用生成器函数时,i 等于 10。它遇到第一个 yield 关键字:它产生 i 的值。生成器当初是“暂停”的,10 被记录。

而后,咱们应用 next() 办法再次调用该函数。它开始在之前进行的中央持续,依然是 i 等于 10。当初,它遇到下一个 yield 关键字,并产生 i*2i 等于 10,所以它返回 10*2,也就是 20。后果是 10,20


三、

Answer:C

应用 yield 关键字,咱们在生成器函数中产生值。应用 yield * 关键字,咱们能够从另一个生成器函数或可迭代对象(例如,数组)中产生值。在 generatorOne 中,咱们应用 yield 关键字产生整个数组 ['a','b','c']。一个对象的下一个办法(one.next()。value) 返回的对象的 value 属性值等于整个数组['a','b','c']

console.log(one.next().value) // ['a', 'b', 'c']
console.log(one.next().value) // undefined

generatorTwo中,咱们应用 yield * 关键字。这意味着咱们失去的迭代器为数组 ['a','b','c']。第一个产生的值为数组中的第一个值 a,因而咱们第一次调用two.next().value 时,将返回 a。前面持续调用 next() 则会继续返回 bc直到该数组调用完结。。

console.log(two.next().value) // 'a'
console.log(two.next().value) // 'b'
console.log(two.next().value) // 'c'
console.log(two.next().value) // undefined

正文完
 0