generator

Generator简介

先来一段最基础的Generator代码

function* Hello() {
    yield 100
    yield (function () {return 200})()
    return 300
}

var h = Hello()
console.log(typeof h)  // object

console.log(h.next())  // { value: 100, done: false }
console.log(h.next())  // { value: 200, done: false }
console.log(h.next())  // { value: 300, done: true }
console.log(h.next())  // { value: undefined, done: true }

在 nodejs 环境执行这段代码,打印出来的数据都在代码注释中了,也可以自己去试试。将这段代码简单分析一下吧

  • 定义Generator时,需要使用function*,其他的和定义函数一样。内部使用yield,至于yield的用处以后再说
  • 执行var h = Hello()生成一个Generator对象,经验验证typeof h发现不是普通的函数
  • 执行Hello()之后,Hello内部的代码不会立即执行,而是出于一个暂停状态
  • 执行第一个h.next()时,会激活刚才的暂停状态,开始执行Hello内部的语句,但是,直到遇到yield语句。一旦遇到yield语句时,它就会将yield后面的表达式执行,并返回执行的结果,然后又立即进入暂停状态。
  • 因此第一个console.log(h.next())打印出来的是{ value: 100, done: false }value是第一个yield返回的值,done: false表示目前处于暂停状态,尚未执行结束,还可以再继续往下执行。
  • 执行第二个h.next()和第一个一样,不在赘述。此时会执行完第二个yield后面的表达式并返回结果,然后再次进入暂停状态
  • 执行第三个h.next()时,程序会打破暂停状态,继续往下执行,但是遇到的不是yield而是return。这就预示着,即将执行结束了。因此最后返回的是{ value: 300, done: true }done: true表示执行结束,无法再继续往下执行了。
  • 再去执行第四次h.next()时,就只能得到{ value: undefined, done: true },因为已经结束,没有返回值了。

一口气分析下来,发现并不是那么简单,虽然这只是一个最最简单的Generator入门代码 ———— 可见Generator的学习成本多高 ———— 但是一旦学会,那将受用无穷!别着急,跟着我的节奏慢慢来,一行一行代码看,你会很快深入了解Genarator

但是,你要详细看一下上面的所有步骤,争取把我写的每一步都搞明白。如果搞不明白细节,至少要明白以下几个要点:

  • Generator不是函数,不是函数,不是函数
  • Hello()不会立即出发执行,而是一上来就暂停
  • 每次h.next()都会打破暂停状态去执行,直到遇到下一个yield或者return
  • 遇到yield时,会执行yeild后面的表达式,并返回执行之后的值,然后再次进入暂停状态,此时done: false
  • 遇到return时,会返回值,执行结束,即done: true
  • 每次h.next()的返回值永远都是{value: ... , done: ...}的形式

Generator最终如何处理异步操作

上面只是一个最基本最简单的介绍,但是我们看不到任何与异步操作相关的事情,那我们接下来就先展示一下最终我们将使用Generator如何做异步操作。

之前讲解Promise时候,依次读取多个文件,我们是这么操作的(看不明白的需要回炉重造哈),主要是使用then做链式操作。

readFilePromise('some1.json').then(data => {
    console.log(data)  // 打印第 1 个文件内容
    return readFilePromise('some2.json')
}).then(data => {
    console.log(data)  // 打印第 2 个文件内容
    return readFilePromise('some3.json')
}).then(data => {
    console.log(data)  // 打印第 3 个文件内容
    return readFilePromise('some4.json')
}).then(data=> {
    console.log(data)  // 打印第 4 个文件内容
})

而如果学会Generator那么读取多个文件就是如下这样写。先不要管如何实现的,光看一看代码,你就能比较出哪个更加简洁、更加易读、更加所谓的优雅!

 

co(function* () {
    const r1 = yield readFilePromise('some1.json')
    console.log(r1)  // 打印第 1 个文件内容
    const r2 = yield readFilePromise('some2.json')
    console.log(r2)  // 打印第 2 个文件内容
    const r3 = yield readFilePromise('some3.json')
    console.log(r3)  // 打印第 3 个文件内容
    const r4 = yield readFilePromise('some4.json')
    console.log(r4)  // 打印第 4 个文件内容
})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值