node.js
4.x版本增加了许多ES6语法特性(如const
/let
/class
/箭头函数)的支持
node.js
6.x版本囊括了绝大多数的ES6语法特性以及部分ES7特性
node.js
8.x版本更支持了ES8语法(如async
/await
)
此后的版本也在频繁不断地更新,纳入许多新特性。
关于NodeJS中异步函数的写法,也在不断进行改善优化:
1. 嵌套回调函数
const fs = require('fs')
fs.readFile('demo.json', (err, data) => {
if(err) return console.log(err)
data = JSON.parse(data)
console.log(data.name)
})
这是NodeJS
中比较原始的一种写法,将回调函数作为异步函数的参数,当异步操作过多,函数不断嵌套,很容易形成回调地狱。
2. Promise
function readFileAsync(path){
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if(err) reject(err)
else resolve(data)
})
})
}
readFileAsync('demo.json')
.then(data => {
data = JSON.parse(data)
console.log(data.name)
})
.catch(err => {
console.log(err)
})
当NodeJS
中开始原生支持Promise
,我们可以将异步函数封装成Promise
,方便后续异步操作,摆脱了不断嵌套的回调函数。
3. Promisify
const util = require('util')
util.promisify(fs.readFile)('demo.json')
.then(JSON.parse)
.then(data => {
console.log(data.name)
})
.catch(err => {
console.log(err)
})
NodeJS
8.x版本在util
模块中新增了一个工具函数promisify
,它将一个接收回调函数参数的函数转换成一个返回Promise
的函数。这样一来我们可以省略自己封装Promise
函数的过程,大大减少了代码体积。
4. async/await
随着ES8规范中提出了async/await
的语法,NodeJS
8.x版本也加入了相应特性的支持,我们可以同时使用这些语法特性来让代码更加简洁易读。
const fs = require('fs')
const util = require('util')
const readAsync = util.promisify(fs.readFile)
async function read(){
try {
let data = await readAsync('demo.json')
data = JSON.parse(data)
console.log(data.name)
} catch (err) {
console.log(err)
}
}
read()
如果服务器上的NodeJS
版本较低,并不支持这些新的语法特性,那么我们可以使用Babel
来将含有较新语法的代码向下编译为兼容运行环境的代码。