如何使用async/await替代js传统回调函数的写法
2017-12-28 本文已影响31人
2f1b6dfcc208
在 js/node.js 中,有很多的操作都是异步的,一般通过回调函数形式返回结果,所以非常容易写出嵌套过深甚至回调地狱的代码,现在ES2017标准已经引入了async
函数,使得异步操作变得更加方便,再也不用担心写出回调地狱了。
以node中内建的fs模块读写文件为例,首先使用传统回调函数的写法:
const fs = require('fs')
const path = require('path')
const srcFile = path.resolve('./1.js')
const distFile = path.resolve('./2.js')
fs.stat(srcFile, (err, stats) => {
if (err) throw err;
if (stats.isFile()) {
fs.readFile(srcFile, 'utf8', (err, data) => {
if (err) throw err;
fs.writeFile(distFile, data, 'utf8', (err) => {
if (err) throw err;
console.log('done!');
})
})
}
})
可以看到,这么简单的一段代码已经嵌套了两层,如果有更复杂的处理逻辑那么嵌套层次将会更深,而且使得代码的可读性变差。
下面使用async改写:
const fs = require('fs')
const path = require('path')
const promisify = require('util').promisify
const stat = promisify(fs.stat)
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const srcFile = path.resolve('./1.js')
const distFile = path.resolve('./2.js')
async function copy() {
try {
const stats = await stat(srcFile)
if (stats.isFile()) {
const data = await readFile(srcFile)
await writeFile(distFile, data)
console.log('done!')
}
} catch (e) {
console.log(e)
}
}
copy()
现在看起来就像同步的一样了,其实很简单,只需要将异步操作包裹成一个Promise
对象,因此当遇到await
时,只有等到异步操作完成,才会继续执行后面的语句。
前端的 js 代码也是一样,如果本身就是一个Promise
对象,则可以直接改写,否则可以通过new Promise
将异步函数包裹起来再进行改写。