站長資訊網
        最全最豐富的資訊網站

        聊聊Node.js中怎么用async函數

        聊聊Node.js中怎么用async函數

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

        什么是 async 函數

        利用 async 函數,你可以把基于 Promise 的異步代碼寫得就像同步代碼一樣。一旦你使用 async 關鍵字來定義了一個函數,那你就可以在這個函數內使用 await 關鍵字。當一個 async 函數被調用時,它會返回一個 Promise。當這個 async 函數返回一個值時,那個 Promise 就會被實現;而如果函數中拋出一個錯誤,那么 Promise 就會被拒絕?!鞠嚓P教程推薦:nodejs視頻教程、編程教學】

        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)
        登錄后復制

        向 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)
        登錄后復制

        Async 函數的最佳實踐

        在 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) }))
        登錄后復制

        并行執行

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

        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 方法。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产精品一区二区久久国产| 老司机国内精品久久久久| 久久ww精品w免费人成| 国产亚洲精品精品国产亚洲综合| 国产成人精品免费视频网页大全| 中文精品久久久久人妻| 国产成人久久精品麻豆一区| 成人午夜精品视频在线观看| 日韩精品亚洲人成在线观看 | 国产成人久久精品一区二区三区| 日韩精品一区二区三区影院| 国产精品自产拍高潮在线观看| 91麻豆精品国产自产在线观看一区| 色婷婷在线精品国自产拍| 中文成人无字幕乱码精品区| 欧美精品91欧美日韩操| 精品国产免费一区二区三区| 国产精品成人久久久久三级午夜电影 | 51视频国产精品一区二区| 久久亚洲私人国产精品| 中文字幕日韩精品无码内射 | 92国产精品午夜福利免费| 久久精品成人免费看| 国产精品美女久久久久网| 2021国产精品视频| 91精品国产综合久久精品| 国产精品亚韩精品无码a在线| 老司机午夜精品视频资源| 亚洲日韩精品A∨片无码| 亚洲国产精品激情在线观看| 日韩午夜高清福利片在线观看欧美亚洲精品suv | 国产午夜福利精品久久2021| 久久精品国产亚洲AV无码娇色| 亚洲精品无码永久中文字幕| 亚洲欧美日韩国产精品影院| 亚洲国产精品无码一线岛国| 久久久精品人妻一区二区三区蜜桃 | 精品国产AV一区二区三区| 国产精品无码无片在线观看| 国精无码欧精品亚洲一区| 国产精品福利自产拍在线观看|