await原理 js_深入理解 JavaScript 异步系列(5)—— async await

本文介绍了ES7中的async/await,它是Generator的语法糖,简化了异步处理。通过对比Generator和async/await,展示了await只能跟Promise对象,执行返回Promise,并提升了代码可读性。在Node v7以后,原生支持async/await,但在v6中需借助babel。文章总结了异步编程的发展,从callback到async/await,体现了代码简洁性和易读性的提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

前面介绍完了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')

}

写在最后

写到这里,也没啥可写的了,这里希望大家多多按照自己的思路来思考问题吧。最后,欢迎扫码转账给我打赏,哈哈!

求打赏

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

93268aab88a4fed2f7289197413d9432.png

------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值