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来将含有较新语法的代码向下编译为兼容运行环境的代码。

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