第一部分,ES7 中引入 async-await
原文地址http://www.cnblogs.com/wangfupeng1988/p/6532734.html 未经作者允许,不得转载~
前面介绍完了 Generator
的异步处理,可以说是跌跌撞撞,经过各种基础介绍和封装,好容易出了一个比较简洁的异步处理方案,学习成本非常高————这显然不是我们想要的!
因此,还未发布的 ES7 就干脆自己参照 Generator
封装了一套异步处理方案————async-await
。说是参照,其实可以理解为是 Generator
的语法糖!
本节示例代码参照这里
本节内容概述
Generator
和async-await
的对比- 使用
async-await
的不同和好处 - 接下来…
Generator
和 async-await
的对比
先来一段 Generator
处理异步的代码,前面已经介绍过了,看不明白的再获取接着看。
co(function* () {
const r1 = yield readFilePromise('some1.json')
console.log(r1) // 打印第 1 个文件内容
const r2 = yield readFilePromise('some2.json')
console.log(r2) // 打印第 2 个文件内容
})
再来一段 async-await
的执行代码如下,两者做一个比较。
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,但是会直接同步执行,而不是异步。
第二,执行 const result = readFileAsync()
返回的是个 Promise
对象,而且上面代码中的 return 'done'
会直接被下面的 then
函数接收到
result.then(data => {
console.log(data) // done
})
第三,从代码的易读性来将, async-await
更加易读简介,也更加符合代码的语意。而且还不用引用第三方库,也无需学习 Generator
那一堆东西,使用成本非常低。
因此,如果 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
Original: https://www.cnblogs.com/wangfupeng1988/p/6532734.html
Author: 王福朋
Title: 深入理解 JavaScript 异步系列(5)—— async await
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/536495/
转载文章受原作者版权保护。转载请注明原作者出处!