国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

在 Node.js 中使用 async 函數的方法

2024-05-06 16:40:58
字體:
來源:轉載
供稿:網友

借助于新版 V8 引擎,Node.js 從 7.6 開始支持 async 函數特性。今年 10 月 31 日,Node.js 8 也開始成為新的長期支持版本,因此你完全可以放心大膽地在你的代碼中使用 async 函數了。在這邊文章里,我會簡要地介紹一下什么是 async 函數,以及它會如何改變我們編寫 Node.js 應用的方式。

1 什么是 async 函數

利用 async 函數,你可以把基于 Promise 的異步代碼寫得就像同步代碼一樣。一旦你使用 async 關鍵字來定義了一個函數,那你就可以在這個函數內使用 await 關鍵字。當一個 async 函數被調用時,它會返回一個 Promise。當這個 async 函數返回一個值時,那個 Promise 就會被實現;而如果函數中拋出一個錯誤,那么 Promise 就會被拒絕。

await 關鍵字可以被用來等待一個 Promise 被解決并返回其實現的值。如果傳給 await 的值不是一個 Promise,那它會把這個值轉化為一個已解決的 Promise。

const rp = require('request-promise')async function main () { const result = await rp('http://m.survivalescaperooms.com') const twenty = await 20 // 睡個1秒鐘 await new Promise (resolve => {  setTimeout(resolve, 1000) }) return result}main() .then(console.log) .catch(console.error)

2 向 async 函數遷移

如果你的 Node.js 應用已經在使用Promise,那你只需要把原先的鏈式調用改寫為對你的這些 Promise 進行 await。

如果你的應用還在使用回調函數,那你應該以漸進的方式轉向使用 async 函數。你可以在開發一些新功能的時候使用這項新技術。當你必須調用一些舊有的代碼時,你可以簡單地把它們包裹成為 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 函數的最佳實踐

3.1 在 express 中使用 async 函數

express 本來就支持 Promise,所以在 express 中使用 async 函數是比較簡單的:

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 路由處理器就會被掛起。

為了修正這個問題,你應該把你的異步處理器包裹在一個對錯誤進行處理的函數中:

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

3.2 并行執行

比如說你正在編寫這樣一個程序,一個操作需要兩個輸入,其中一個來自于數據庫,另一個則來自于一個外部服務:

async function main () { const user = await Users.fetch(userId) const product = await Products.fetch(productId) await makePurchase(user, product)}

在這個例子中,會發生什么呢?

你的代碼會首先去獲取 user,

然后獲取 product,

最后再進行支付。

如你所見,由于前兩步之間并沒有相互依賴關系,其實你完全可以將它們并行執行。這里,你應該使用 Promise.all 方法:

async function main () { const [user, product] = await Promise.all([  Users.fetch(userId),  Products.fetch(productId) ]) await makePurchase(user, product)}

而有時候,你只需要其中最快被解決的 Promise 的返回值——這時,你可以使用 Promise.race 方法。

3.3 錯誤處理

考慮下面這個例子:

async function main () { await new Promise((resolve, reject) => {  reject(new Error('error')) })}main() .then(console.log)

當執行這段代碼的時候,你會看到類似這樣的信息:

(node:69738) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: error

(node:69738) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

在較新的 Node.js 版本中,如果 Promise 被拒絕且未得到處理,整個 Node.js 進程就會被中斷。因此必要的時候你應該使用 try-catch:

const util = require('util')async function main () { try {  await new Promise((resolve, reject) => {   reject(new Error('
注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 澄城县| 平湖市| 吉首市| 合川市| 铁力市| 都江堰市| 景洪市| 南雄市| 缙云县| 银川市| 黔南| 邓州市| 鱼台县| 怀远县| 漯河市| 道真| 五台县| 兰西县| 白沙| 健康| 天峻县| 福鼎市| 怀柔区| 恩平市| 姚安县| 衡山县| 昌黎县| 锦州市| 安西县| 来凤县| 松原市| 偃师市| 广丰县| 大冶市| 丽江市| 丹凤县| 石楼县| 白水县| 上饶市| 东宁县| 宁都县|