如何在Node.js中使用async函數(shù)的方法詳解
前言
借助于新版 V8 引擎,Node.js 從 7.6 開始支持 async 函數(shù)特性。今年 10 月 31 日,Node.js 8 也開始成為新的長期支持版本,因此你完全可以放心大膽地在你的代碼中使用 async 函數(shù)了。在這邊文章里,我會簡要地介紹一下什么是 async 函數(shù),以及它會如何改變我們編寫 Node.js 應用的方式。
什么是 async 函數(shù)
利用 async 函數(shù),你可以把基于 Promise 的異步代碼寫得就像同步代碼一樣。一旦你使用 async 關鍵字來定義了一個函數(shù),那你就可以在這個函數(shù)內使用 await 關鍵字。當一個 async 函數(shù)被調用時,它會返回一個 Promise。當這個 async 函數(shù)返回一個值時,那個 Promise 就會被實現(xiàn);而如果函數(shù)中拋出一個錯誤,那么 Promise 就會被拒絕。
await 關鍵字可以被用來等待一個 Promise 被解決并返回其實現(xiàn)的值。如果傳給 await 的值不是一個 Promise,那它會把這個值轉化為一個已解決的 Promise。
const rp = require('request-promise')
async function main () {
const result = await rp('https://google.com')
const twenty = await 20
// 睡個1秒鐘
await new Promise (resolve => {
setTimeout(resolve, 1000)
})
return result
}
main()
.then(console.log)
.catch(console.error)
向 async 函數(shù)遷移
如果你的 Node.js 應用已經在使用Promise,那你只需要把原先的鏈式調用改寫為對你的這些 Promise 進行 await。
如果你的應用還在使用回調函數(shù),那你應該以漸進的方式轉向使用 async 函數(shù)。你可以在開發(fā)一些新功能的時候使用這項新技術。當你必須調用一些舊有的代碼時,你可以簡單地把它們包裹成為 Promise 再用新的方式調用。
要做到這一點,你可以使用內建的 util.promisify方法:
const util = require('util')
const {readFile} = require('fs')
const readFileAsync = util.promisify(readFile)
async function main () {
const result = await readFileAsync('.gitignore')
return result
}
main()
.then(console.log)
.catch(console.error)
3 Async 函數(shù)的最佳實踐
在 express 中使用 async 函數(shù)
express 本來就支持 Promise,所以在 express 中使用 async 函數(shù)是比較簡單的:
const express = require('express')
const app = express()
app.get('/', async (request, response) => {
// 在這里等待 Promise
// 如果你只是在等待一個單獨的 Promise,你其實可以直接將將它作為返回值返回,不需要使用 await 去等待。
const result = await getContent()
response.send(result)
})
app.listen(process.env.PORT)
但正如 Keith Smith 所指出的,上面這個例子有一個嚴重的問題——如果 Promise 最終被拒絕,由于這里沒有進行錯誤處理,那這個 express 路由處理器就會被掛起。
為了修正這個問題,你應該把你的異步處理器包裹在一個對錯誤進行處理的函數(shù)中:
const awaitHandlerFactory = (middleware) => {
return async (req, res, next) => {
try {
await middleware(req, res, next)
} catch (err) {
next(err)
}
}
}
// 然后這樣使用:
app.get('/', awaitHandlerFactory(async (request, response) => {
const result = await getContent()
response.send(result)
}))
并行執(zhí)行
比如說你正在編寫這樣一個程序,一個操作需要兩個輸入,其中一個來自于數(shù)據(jù)庫,另一個則來自于一個外部服務:
async function main () {
const user = await Users.fetch(userId)
const product = await Products.fetch(productId)
await makePurchase(user, product)
}
在這個例子中,會發(fā)生什么呢?
你的代碼會首先去獲取 user,
然后獲取 product,
最后再進行支付。
如你所見,由于前兩步之間并沒有相互依賴關系,其實你完全可以將它們并行執(zhí)行。這里,你應該使用 Promise.all 方法:
async function main () {
const [user, product] = await Promise.all([
Users.fetch(userId),
Products.fetch(productId)
])
await makePurchase(user, product)
}
而有時候,你只需要其中最快被解決的 Promise 的返回值——這時,你可以使用 Promise.race 方法。
以上就是如何在Node.js中使用async函數(shù)的方法詳解的詳細內容,更多關于Node.js使用async函數(shù)的資料請關注腳本之家其它相關文章!
相關文章
讓nodeJS支持ES6的詞法----babel的安裝和使用方法
這篇文章主要介紹了讓nodeJS支持ES6的詞法----babel的安裝和使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
詳解Nodejs 通過 fs.createWriteStream 保存文件
本篇文章主要介紹了Nodejs 通過 fs.createWriteStream 保存文件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
node.js中的fs.createReadStream方法使用說明
這篇文章主要介紹了node.js中的fs.createReadStream方法使用說明,本文介紹了fs.createReadStream方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下2014-12-12
node.js使用net模塊創(chuàng)建服務器和客戶端示例【基于TCP協(xié)議】
這篇文章主要介紹了node.js使用net模塊創(chuàng)建服務器和客戶端,結合實例形式分析了node.js使用net模塊實現(xiàn)TCP客戶端與服務器端通信的相關操作技巧,需要的朋友可以參考下2020-02-02
理解nodejs的stream和pipe機制的原理和實現(xiàn)
本篇文章主要介紹了理解nodejs的stream和pipe機制的原理和實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08

