【ES6】ES6 Generator——ES7 Async +Await

前言:每一个特性的出现,总有它的用途,而只有用了,才能更好地理解它。不管是Generator,还是Async +Await,还有Promise都是为了解决异步而存在;存在及合理;这些知识是自己整理得来的,一边学习,一边加深印象巩固,可能不是那样完美,也有缺漏,欢迎补充;这些内容可能在项目中用不上,但是也可以了解很多概念性的知识;像我之前都没听过Generator,但是在学Async +Await的时候,还是先了解Generator比较好;

写这个文章之前也写了Promise,同步异步 的一些知识,不懂的可以过去看看,欢迎补充完善

【JavaScript 】运行机制详解 同步 异步 Event Loop
【ES6 】Promise 在 ES6 中的基本应用

接下来我们进入正题:

什么是Generator?

  • 语法上,可以把理解成,Generator 函数是一个状态机,封装了多个内部状态。(但是这丫的不是函数,切记)
  • 形式上,Generator 函数是一个普通函数。

整个Generator函数就是一个封装的异步任务,或者说是异步任务的容器,异步操作需要暂停的地方,都用yield语句。

Generator 函数的语法

function *G() {
    yield 100    
}
const g = G()
console.log( g.next() ) // {value: 100, done: false}

yield 和 next 关键字

先看一段代码

function *G() {
    const a = yield 100
    const b = yield 200
    const c = yield 300
}
const g = G()
console.log(g.next())    // value: 100, done: false
console.log(g.next())    // value: 200, done: false
console.log(g.next())    // value: 300, done: false
console.log(g.next())    // value: undefined, done: true

先简单分析一下代码

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

yield通过如上代码示例可得出:

  • g()不会立即出发执行,而是一上来就暂停
  • yield具有数据返回功能, yield后面的数据会被返回,返回的数据存放在value数据中
  • 遇到yield时,会执行yeild后面的表达式,并返回执行之后的值,然后再次进入暂停状态,此时done: false
  • 遇到return时,会返回值,执行结束,即done: true;
  • 每次g.next()的返回值永远都是{value: ... , done: ...}的形式

nextyield传递

Generator最终如何处理异步操作

先来一段Promise的操作,做一下对比

//今天先写到这里  有时间接着补充

async 函数是什么?

从最早的回调函数,到promise,再到Generator,每次都有改进,但也有一些不彻底,一直在进步,改进怎么样才能更优雅的解决异步,于是asyne出现了;
async就是Generator函数的语法糖,使用,
关键字 async 来表示,在函数内部使用 await来表示异步。

它有以下几个特点:

  • 建立在 promise 之上。所以,不能把它和回调函数搭配使用。但它会声明一个异步函数,并隐式地返回一个Promise。因此可以直接return变量,无需使用 Promise.resolve 进行转换。
  • 和 promise 一样,是非阻塞的。但不用写 then 及其回调函数,这减少代码行数,也避免了代码嵌套。而且,所有异步调用,可以写在同一个代码块中,无需定义多余的中间变量。
  • 它的最大价值在于,可以使异步代码,在形式上,更接近于同步代码。
  • 它总是与 await 一起使用的。并且,await 只能在 async 函数体内。
  • await 是个运算符,用于组成表达式,它会阻塞后面的代码。如果等到的是 Promise 对象,则得到其 resolve 值。否则,会得到一个表达式的运算结果。

你可能感兴趣的:(ES6)