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
來將含有較新語法的代碼向下編譯爲兼容運行環境的代碼。