2018年已经到了5月份,node的4.x版本也已经停止了维护我司的某个服务也已经切到了8.x,目前正在做koa2.x的迁移将之前的generator全部替换为async但是,在替换的过程中,发现一些滥用async导致的时间上的浪费 所以来谈一下,如何优化async代码,更充分的利用异步事件流 杜绝滥用async
首先,你需要了解Promise
Promise是使用async/await的基础,所以你一定要先了解Promise是做什么的
Promise是帮助解决回调地狱的一个好东西,能够让异步流程变得更清晰。
一个简单的Error-first-callback转换为Promise的例子:
const fs = require('fs')function readFile (fileName) { return new Promise((resolve, reject) => { fs.readFile(fileName, (err, data) => { if (err) reject(err) resolve(data) }) })}readFile('test.log').then(data => { console.log('get data')}, err => { console.error(err)})
我们调用函数返回一个Promise的实例,在实例化的过程中进行文件的读取,当文件读取的回调触发式,进行Promise状态的变更,resolved或者rejected状态的变更我们使用then来监听,第一个回调为resolve的处理,第二个回调为reject的处理。
async与Promise的关系
async函数相当于一个简写的返回Promise实例的函数,效果如下:
function getNumber () { return new Promise((resolve, reject) => { resolve(1) })}// =>async function getNumber () { return 1}
两者在使用上方式上完全一样,都可以在调用getNumber函数后使用then进行监听返回值。 以及与async对应的await语法的使用方式:
getNumber().then(data => { // got data})// =>let data = await getNumber()
await的执行会获取表达式后边的Promise执行结果,相当于我们调用then获取回调结果一样。 P.S. 在async/await支持度还不是很高的时候,大家都会选择使用generator/yield结合着一些类似于co的库来实现类似的效果
async函数代码执行是同步的,结果返回是异步的
async函数总是会返回一个Promise的实例 这点儿很重要所以说调用一个async函数时,可以理解为里边的代码都是处于new Promise中,所以是同步执行的而最后return的操作,则相当于在Promise中调用resolve:
async function getNumber () { console.log('call getNumber()') return 1}getNumber().then(_ => console.log('resolved'))console.log('done')// 输出顺序:// call getNumber()// done// resolved
Promise内部的Promise会被消化
也就是说,如果我们有如下的代码:
function getNumber () { return new Promise(resolve => { resolve(Promise.resolve(1)) })}getNumber().then(data => console.log(data)) // 1
如果按照上边说的话,我们在then里边获取到的data应该是传入resolve中的值 ,也就是另一个Promise的实例。
新闻热点
疑难解答
图片精选