亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

async 函數如何在Node.js中使用

發布時間:2021-03-17 15:02:42 來源:億速云 閱讀:170 作者:Leah 欄目:web開發

本篇文章為大家展示了 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('https://google.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('---'))
  })
 } catch (err) {
  // 在這里處理錯誤
  // 根據你的需要,有時候把錯誤直接再拋出也是可行的
 }
}
main()
 .then(console.log)
 .catch(console.error)

可是,使用 try-catch 可能會隱藏掉一些重要的異常,比如像系統錯誤,你可能更想把它再拋出來。關于在什么情況下你應該將錯誤再次拋出,我強烈建議你去讀一下 Eran 的這篇文章。

3.4 更為復雜的流程控制

Caolan McMahon 的 async 是一個出現較早的用于 Node.js 中異步流程控制的庫。它提供了一些進行異步操作控制的幫助工具,比如:

mapLimit,
filterLimit,
concatLimit,

以及 priorityQueue。

如果你不打算重新發明輪子,不想把同樣的邏輯自己再實現一遍,并且愿意信賴這個經過實踐檢驗的、每月下載量高達 5000 萬的庫,你可以結合 util.promisify 簡單地重用這些函數:

const util = require('util')
const async = require('async')
const numbers = [
 1, 2, 3, 4, 5
]
mapLimitAsync = util.promisify(async.mapLimit)
async function main () {
 return await mapLimitAsync(numbers, 2, (number, done) => {
  setTimeout(function () {
   done(null, number * 2)
  }, 100)
 })
}
main()
 .then(console.log)
 .catch(console.error)

上述內容就是 async 函數如何在Node.js中使用,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

陇西县| 拜泉县| 金寨县| 旬阳县| 奉化市| 乌拉特前旗| 怀集县| 高邮市| 阜宁县| 霍林郭勒市| 鸡西市| 赫章县| 徐州市| 天全县| 阿巴嘎旗| 丘北县| 黑河市| 社旗县| 陕西省| 桐乡市| 陈巴尔虎旗| 夏邑县| 郧西县| 鄢陵县| 建始县| 集贤县| 尚义县| 正镶白旗| 买车| 融水| 荣昌县| 辰溪县| 赣榆县| 如东县| 西昌市| 荆门市| 虎林市| 隆子县| 黄冈市| 彭水| 淮滨县|