目录

  • ES6如何让遍历“停”下来
  • Basic Syntax —— 根底语法
  • Senior Syntax —— 高级语法

    • next增加参数
    • return管制完结
    • throw抛出异样管制
  • Scene Pratice —— 案例

    • 抽奖
    • 数3的倍数小游戏
    • 应用Generator函数实现Iterator办法
  • ES6-ES10学习幅员

ES6如何让遍历“停”下来

ES5循环一旦执行,无奈停下来的

function loop() {  for(let i = 0; i < 5; i++) {    console.log(i)  }}loop()// 0// 1// 2// 3// 5

应用Generator,怎么革新?

// 批改一,在loop后面加一个星号function * loop() {  for(let i = 0; i < 5; i++) {  // 批改二:在输入后面加yield    yield console.log(i)  }}// 批改三:定义一个变量将loop赋值给lconst l = loop()// 这个时候并没有输入,若要输入调用next办法l.next() // 0l.next() // 1l.next() // 2l.next() // 3l.next() // 4l.next() // 之后不会输入任何货色//利用场景:年会抽奖、自定义遍历器

Basic Syntax —— 根底语法

  1. 遍历器就是一个函数,然而与一般的函数不同。
  2. 函数外部能够应用yield停下来
  3. 应用实例调用next管制循环
  4. Generator函数的定义不能应用箭头函数,否则会登程报错SyntaxError
function * gen() {  let val  val = yield 1  console.log(val)}const l = gen()// "Generator { }"l.next() // 没有任何输入l.next() // undefined  yield表达式没有返回值,所以返回undefined

next()的返回值

第一个参数是返回的值,

第二个参数是是否遍历实现,false是没有遍历完,true是遍历实现

function * gen() {  let val  val = yield [1, 2, 3]  console.log(val) // undefined}const l = gen()console.log(l.next()) // {value: Array(3), done: false}console.log(l.next()) // {value: undefined, done: true}
function * gen() {  let val  // yield 前面加了一个星号,前面是一个遍历的对象,所以能够嵌套一个Generator对象  val = yield * [1, 2, 3]  console.log(val) // undefined}const l = gen()console.log(l.next()) // {value: 1, done: false}console.log(l.next()) // {value: 2, done: false}

学到这里要明确:

  1. Generator是做什么用的?<br/>

管制循环流程用的<br/>
最重要的作用是解决异步编程嵌套层级较深的问题。

  1. yield有没有返回值?<br/>

没有,然而遍历器对象的next办法能够批改这个默认值

  1. ES5相比,是如何控制程序的进行和启动的?<br/>

应用yield去管制进行,应用next去管制启动

Senior Syntax —— 高级语法

如何在函数内部管制函数外部的运行?

next增加参数

next函数写参数,作为yield的返回值

function * gen() {  let val  val = yield [1, 2, 3]  console.log(val) // 20}const l = gen()console.log(l.next(10))// {value: Array(3), done: false}// 此时yield没有赋值,所以10并没有用console.log(l.next(20))// {value: undefined, done: true}// 此时yield对val进行赋值操作,yield表达式的值是20

讲义的例子能够了解更粗浅

function * gen() {  var val = 100  while(true){    console.log(`before${val}`)    val = yield val    console.log(`return ${val}`)  }}let g = gen()console.log(g.next(20).value)// before 100// 100console.log(g.next(30).value)// return 30// before 30// 30console.log(g.next(40).value)// return 40// before 40// 40
1.g.next(20) 这句代码会执行 gen 外部的代码,遇到第一个 yield 暂停。所以 console.log("before "+val) 执行输入了 before 100,此时的 val100,所以执行到 yield val 返回了 100,留神 yield val 并没有赋值给 val

2.g.next(30) 这句代码会继续执行 gen 外部的代码,也就是 val = yield val 这句,因为 next 传入了 30,所以 yield val 这个返回值就是 30,因而 val 被赋值 30,执行到console.log("return "+val)输入了 30,此时没有遇到 yield 代码继续执行,也就是 while 的判断,继续执行console.log("before "+val) 输入了 before 30,再执行遇到了yield val程序暂停。

3.g.next(40) 反复步骤 2

return管制完结

function * gen() {  let val  val = yield [1, 2, 3]  console.log(val) // 没有执行}const l = gen()console.log(l.next(10))// {value: Array(3), done: false}console.log(l.return())// {value: undefined, done: true}//返回操作,函数终止console.log(l.next(20))// {value: undefined, done: true}

增加返回值的参数

function * gen() {  let val  val = yield [1, 2, 3]  console.log(val) // 没有执行}const l = gen()console.log(l.next(10))// {value: Array(3), done: false}console.log(l.return(100))// {value: 100, done: true}//返回操作,函数终止console.log(l.next(20))// {value: undefined, done: true}

throw抛出异样管制

function * gen() {  while (true) {    try {      yield 1    } catch (e) {      console.log(e.message) // ss    }  }}const l = gen()console.log(l.next())//{value: 1, done: false}console.log(l.next())//{value: 1, done: false}console.log(l.next())//{value: 1, done: false}l.throw(new Error('ss')) // 抛出谬误,执行catchconsole.log(l.next()) //{value: 1, done: false}

Scene Pratice —— 案例

抽奖

ES5

function draw (first = 1, second = 3, third = 5) {  // 三个奖的候选人,一个后果,一个随机数  let firstPrize = ['1A', '1B', '1C', '1D', '1E']  let secondPrize = ['2A', '2B', '2C', '2D', '2E', '2F', '2G', '2H', '2I', '2J', '2K', '2L']  let thirdPrize = ['3A', '3B', '3C', '3D', '3E', '3F', '3G', '3H', '3I', '3J', '3K', '3L', '3M', '3N', '3O', '3P', '3Q', '3R', '3S', '3T', '3U', '3V', '3W', '3X', '3Y', '3Z']  let result = []  let random  // 抽一等奖  for(let i = 0; i < first; i++){    random = Math.floor(Math.random() * firstPrize.length)    result = result.concat(firstPrize.splice(random, 1))  }  // 抽二等奖  for(let i = 0; i < second; i++){    random = Math.floor(Math.random() * secondPrize.length)    result = result.concat(secondPrize.splice(random, 1))  }  // 抽三等奖  for(let i = 0; i < third; i++){    random = Math.floor(Math.random() * thirdPrize.length)    result = result.concat(thirdPrize.splice(random, 1))  }  return result}console.log(draw())// ["1A", "2D", "2K", "2A", "3A", "3G", "3Y", "3W", "3P"]

ES6

function * draw (first = 1, second = 3, third = 5) {  // 三个奖的候选人,一个后果,一个随机数  let firstPrize = ['1A', '1B', '1C', '1D', '1E']  let secondPrize = ['2A', '2B', '2C', '2D', '2E', '2F', '2G', '2H', '2I', '2J', '2K', '2L']  let thirdPrize = ['3A', '3B', '3C', '3D', '3E', '3F', '3G', '3H', '3I', '3J', '3K', '3L', '3M', '3N', '3O', '3P', '3Q', '3R', '3S', '3T', '3U', '3V', '3W', '3X', '3Y', '3Z']  let count = 0  let random  while(1){    if (count < first) {      random = Math.floor(Math.random() * firstPrize.length)      yield firstPrize[random]      count ++      firstPrize.splice(random, 1)    } else if (count < first + second) {      random = Math.floor(Math.random() * secondPrize.length)      yield secondPrize[random]      count ++      secondPrize.splice(random, 1)    } else if (count < first + second + third) {      random = Math.floor(Math.random() * thirdPrize.length)      yield thirdPrize[random]      count ++      thirdPrize.splice(random, 1)    } else {      return false    }  }  }let d = draw()console.log(d.next().value) // 1Cconsole.log(d.next().value) // 2Econsole.log(d.next().value) // 2Hconsole.log(d.next().value) // 2Cconsole.log(d.next().value) // 3Hconsole.log(d.next().value) // 3Vconsole.log(d.next().value) // 3Aconsole.log(d.next().value) // 3Jconsole.log(d.next().value) // 3Nconsole.log(d.next().value) // falseconsole.log(d.next().value) // undefinedconsole.log(d.next().value) // undefined

数3的倍数小游戏

如果是ES5,是有限死循环,程序解体

ES6

function * count (x = 1) {  while (1) {    if (x % 3 === 0) {      yield x    }    x++  }}let num = count()console.log(num.next().value) // 3console.log(num.next().value) // 6console.log(num.next().value) // 9console.log(num.next().value) // 12console.log(num.next().value) // 15console.log(num.next().value) // 18...

应用Generator函数实现Iterator办法

const todos = {  life: ['吃饭', '睡觉', '打豆豆'],  learn: ['语文', '数学', '外语'],  work: ['喝茶'],  each: function (callback) {    const all = [].concat(this.life, this.learn, this.work)    for( const item of all) {      callback(item)    }  },  [Symbol.iterator]: function * () {    const all = [...this.life, ...this.learn, ...this.work]    for(const item of all) {      yield item    }  }}for(const item of todos){  console.log(item)}// 吃饭// 睡觉// 打豆豆// 语文// 数学// 外语// 喝茶

学习幅员