寫在前面
一場(chǎng)大雪,整個(gè)杭城銀裝素裹灭美,外面太冷就待在家里寫點(diǎn)東西吧珊皿。這次就來(lái)簡(jiǎn)單談?wù)凬ode.js中異步編程的幾種寫法。
環(huán)境準(zhǔn)備
- 編輯器vscode
- 本地node環(huán)境(8.9.x)
本文內(nèi)容
在我們工作中異步變成應(yīng)該是非常常見的垮刹,請(qǐng)求接口,定時(shí)器张弛,讀取文件等等荒典。本篇文章主要通過(guò)一個(gè)讀取文件的例子簡(jiǎn)單介紹一下Node.js應(yīng)用中如何從 CallBack方式 ——> Promise方式 ——> 使用util.promisify ——> async/await方式酪劫,讓代碼變得酷炫點(diǎn)
回調(diào)方式
假設(shè)我們本地有一個(gè)文件名為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)
})
缺點(diǎn):
- 回調(diào)地域(異步請(qǐng)求嵌套多了就很凌亂)
- 不能捕獲異常(try catch同步執(zhí)行)
- 看著不夠酷覆糟,現(xiàn)在都是2018年了
自己寫promise
既然上面的代碼不夠酷,那我們現(xiàn)在自己寫個(gè)Promise遮咖,讓它簡(jiǎn)化一下
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)
})
這樣是不是看起來(lái)好多了滩字,邏輯清晰,還可以統(tǒng)一捕獲失斢獭(目前這種方式用的人應(yīng)該挺多的)
使用util.promisify
每次自己寫個(gè)Promise太累了吧麦箍?是的沒錯(cuò),還好Node 8中提供了一個(gè)util.promisify來(lái)幫助我們陶珠,那我們就不要重復(fù)造輪子了挟裂,愉快的引入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)
})
是不是清爽很多揍诽?還不用自己動(dòng)手寫Promise太爽话瞧。
async與await
有人說(shuō)既然說(shuō)是2018年了,那還不用async/await寝姿?別急我們這就來(lái)試試(現(xiàn)在的Node版本中已經(jīng)可以支持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()
怎么樣這樣寫夠時(shí)尚了吧交排,最新的async/await也用上了。