寫在前面
一場大雪,整個杭城銀裝素裹,外面太冷就待在家裡寫點東西吧。這次就來簡單談談Node.js中非同步程式設計的幾種寫法。
環境準備
- 編輯器vscode
- 本地node環境(8.9.x)
本文內容
在我們工作中非同步變成應該是非常常見的,請求介面,定時器,讀取檔案等等。本篇文章主要通過一個讀取檔案的例子簡單介紹一下Node.js應用中如何從 CallBack方式 ——> Promise方式 ——> 使用util.promisify ——> async/await方式,讓程式碼變得酷炫點
回撥方式
假設我們本地有一個檔名為test.json,下面是最原始的讀取檔案的方式,相信大家都很熟悉
// callback.js
const fs = require('fs')
fs.readFile('./test.json', (err, data) => {
if (err) return console.log(err)
data = JSON.parse(data)
console.log(data.name)
})
複製程式碼
缺點:
- 回撥地域(非同步請求巢狀多了就很凌亂)
- 不能捕獲異常(try catch同步執行)
- 看著不夠酷,現在都是2018年了
自己寫promise
既然上面的程式碼不夠酷,那我們現在自己寫個Promise,讓它簡化一下
const fs = require('fs')
function readFileAsync (path) {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if (err) reject(err)
else resolve(data)
})
})
}
readFileAsync('./test.json')
.then(data => {
data = JSON.parse(data)
console.log(data.name)
}).catch(err => {
console.log(err)
})
複製程式碼
這樣是不是看起來好多了,邏輯清晰,還可以統一捕獲失敗(目前這種方式用的人應該挺多的)
使用util.promisify
每次自己寫個Promise太累了吧?是的沒錯,還好Node 8中提供了一個util.promisify來幫助我們,那我們就不要重複造輪子了,愉快的引入util工具類,改造程式碼
const util = require('util')
util.promisify(fs.readFile)('./test.json')
.then(JSON.parse)
.then(data => {
console.log(data.name)
}).catch(err => {
console.log(err)
})
複製程式碼
是不是清爽很多?還不用自己動手寫Promise太爽。
async與await
有人說既然說是2018年了,那還不用async/await?別急我們這就來試試(現在的Node版本中已經可以支援async/await了)
const fs = require('fs')
const util = require('util')
const readAsync = util.promisify(fs.readFile)
async function init () {
try {
let data = await readAsync('./test.json')
data = JSON.parse(data)
console.log(data.name)
} catch (err) {
console.log(err)
}
}
init()
複製程式碼
怎麼樣這樣寫夠時尚了吧,最新的async/await也用上了。