Node.js中異步函數的代碼演進

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)
  })

NodeJS8.x版本在util模塊中新增了一個工具函數promisify,它將一個接收回調函數參數的函數轉換成一個返回Promise的函數。這樣一來我們可以省略自己封裝Promise函數的過程,大大減少了代碼體積。

4. async/await

隨着ES8規範中提出了async/await的語法,NodeJS8.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來將含有較新語法的代碼向下編譯爲兼容運行環境的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章