深刻理解 JavaScript 异步系列(5)—— async await

第一部分,ES7 中引入 async-await

原文地址 http://www.cnblogs.com/wangfupeng1988/p/6532734.html 未经做者容许,不得转载~html

前面介绍完了Generator的异步处理,能够说是跌跌撞撞,通过各类基础介绍和封装,好容易出了一个比较简洁的异步处理方案,学习成本很是高————这显然不是咱们想要的!前端

所以,还未发布的 ES7 就干脆本身参照Generator封装了一套异步处理方案————async-await。说是参照,其实能够理解为是Generator的语法糖!node

本节示例代码参照这里git

本节内容概述

  • Generatorasync-await的对比
  • 使用async-await的不一样和好处
  • 接下来...

Generatorasync-await的对比

先来一段Generator处理异步的代码,前面已经介绍过了,看不明白的再获取接着看。github

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

再来一段async-await的执行代码以下,二者作一个比较。web

const readFilePromise = Q.denodeify(fs.readFile)

// 定义 async 函数
const readFileAsync = async function () {
    const f1 = await readFilePromise('data1.json')
    const f2 = await readFilePromise('data2.json')
    console.log('data1.json', f1.toString())
    console.log('data2.json', f2.toString())

    return 'done' // 先忽略,后面会讲到
}
// 执行
const result = readFileAsync()

从上面两端代码比较看来,async function代替了function*await代替了yield,其余的再没有什么区别了。哦,还有,使用async-await时候不用再引用co这种第三方库了,直接执行便可。面试

使用async-await的不一样和好处

第一,await后面不能再跟thunk函数,而必须跟一个Promise对象(所以,Promise才是异步的终极解决方案和将来)。跟其余类型的数据也OK,可是会直接同步执行,而不是异步。npm

第二,执行const result = readFileAsync()返回的是个Promise对象,并且上面代码中的return 'done'会直接被下面的then函数接收到json

result.then(data => {
    console.log(data)  // done
})

第三,从代码的易读性来将,async-await更加易读简介,也更加符合代码的语意。并且还不用引用第三方库,也无需学习Generator那一堆东西,使用成本很是低。babel

所以,若是 ES7 正式发布了以后,强烈推荐使用async-await。可是如今还没有正式发布,从稳定性考虑,仍是Generator更好一些。

接下来...

node v7 版本已经开始原生支持async-await了,不过 node 的目前稳定版本仍是v6,尚不支持,怎么办?———— 固然是万能的babel!下一节就介绍。

 

第二部分,如何在 nodejs v6.x版本中使用 async-await

本节介绍一下如何使用babel来让 node v6 版本也能运行async-await

本节内容概述

  • 安装必要的插件
  • 建立入口文件并执行

安装必要的插件

运行npm i babel-core babel-plugin-transform-runtime babel-preset-es2015 babel-preset-stage-3 babel-runtime --save安装一堆须要的插件。

而后在项目根目录建立.babelrc文件,文件内容编写为

{
  "presets": ["stage-3", "es2015"],
  "plugins": ["transform-runtime"]
}

建立入口文件并执行

加入你编写async-await的代码文件是test.js,那么你须要建立另外一个文件,例如test-entry.js做为入口文件。入口文件内容编写为

require("babel-core/register");
require("./test.js");

而后直接运行node test-entry.js就能够了

 

第三部分,总体总结

一周左右的业余时间总结完,写完,也是累得我够呛。不算什么体力活,可是每天的坐在书桌旁写这些东西也是很考验一我的的定力,没点耐性是确定不行的 ———— 这算是获奖感言吗 😂

本节内容概述

  • 基础知识不可忽略
  • 异步操做代码的变化
  • 写在最后

础知识不可忽略

这里的基础知识分为两部分,都不能忽略,都须要深刻研究和思考

  • 什么是异步,异步的实现原理,event-loop,以及和事件绑定的关系。这些在最初介绍时,都讲过,不要看完了就忘记了;
  • 不管异步操做的写法如何变化,JS 仍是单线程、异步执行的语言,callback一直都存在并且发挥做用,这个在此前的章节一直强调;

异步操做代码的变化

最后咱们来感觉一下,从一开始callback方式到后来的async-await方式,前先后后编写异步代码的变化。从变化中就能够体会到,确实愈来愈简洁,愈来愈易读。

callback方式

fs.readFile('some1.json', (err, data) => {
    fs.readFile('some2.json', (err, data) => {
        fs.readFile('some3.json', (err, data) => {
            fs.readFile('some4.json', (err, data) => {

            })
        })
    })
})

Promise方式

readFilePromise('some1.json').then(data => {
    return readFilePromise('some2.json')
}).then(data => {
    return readFilePromise('some3.json')
}).then(data => {
    return readFilePromise('some4.json')
})

Generator方式

co(function* () {
    const r1 = yield readFilePromise('some1.json')
    const r2 = yield readFilePromise('some2.json')
    const r3 = yield readFilePromise('some3.json')
    const r4 = yield readFilePromise('some4.json')
})

async-await方式

const readFileAsync = async function () {
    const f1 = await readFilePromise('data1.json')
    const f2 = await readFilePromise('data2.json')
    const f3 = await readFilePromise('data3.json')
    const f4 = await readFilePromise('data4.json')
}

写在最后

写到这里,也没啥可写的了,这里但愿你们多多按照本身的思路来思考问题吧。最后,欢迎扫码转帐给我打赏,哈哈!

求打赏

若是你看完了,感受还不错,欢迎给我打赏 ———— 以激励我更多输出优质内容

最后,github地址是 https://github.com/wangfupeng1988/js-async-tutorial 欢迎 star 和 pr

------

学习做者教程:《前端JS高级面试》《前端JS基础面试题》《React.js模拟大众点评webapp》《zepto设计与源码分析》《json2.js源码解读

相关文章
相关标签/搜索