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

首頁 > 語言 > JavaScript > 正文

詳解Node.js中的Async和Await函數

2024-05-06 15:21:38
字體:
來源:轉載
供稿:網友

在本文中,你將學習如何使用Node.js中的async函數(async/await)來簡化callback或Promise.

異步語言結構在其他語言中已經存在了,像c#的async/await、Kotlin的coroutines、go的goroutines,隨著Node.js 8的發布,期待已久的async函數也在其中默認實現了。

Node中的async函數是什么?

當函數聲明為一個Async函數它會返回一個 AsyncFunction 對象,它們類似于 Generator 因為執可以被暫停。唯一的區別是它們返回的是 Promise 而不是 { value: any, done: Boolean } 對象。不過它們還是非常相似,你可以使用 co 包來獲取同樣的功能。

在async函數中,可以等待 Promise 完成或捕獲它拒絕的原因。

如果你要在Promise中實現一些自己的邏輯的話

function handler (req, res) { return request('https://user-handler-service') .catch((err) => {  logger.error('Http error', err)  error.logged = true  throw err }) .then((response) => Mongo.findOne({ user: response.body.user })) .catch((err) => {  !error.logged && logger.error('Mongo error', err)  error.logged = true  throw err }) .then((document) => executeLogic(req, res, document)) .catch((err) => {  !error.logged && console.error(err)  res.status(500).send() })}

可以使用 async/await 讓這個代碼看起來像同步執行的代碼

async function handler (req, res) { let response try { response = await request('https://user-handler-service')  } catch (err) { logger.error('Http error', err) return res.status(500).send() } let document try { document = await Mongo.findOne({ user: response.body.user }) } catch (err) { logger.error('Mongo error', err) return res.status(500).send() } executeLogic(document, req, res)}

在老的v8版本中,如果有有個 promise 的拒絕沒有被處理你會得到一個警告,可以不用創建一個拒絕錯誤監聽函數。然而,建議在這種情況下退出你的應用程序。因為當你不處理錯誤時,應用程序處于一個未知的狀態。

process.on('unhandledRejection', (err) => {  console.error(err) process.exit(1)})

async函數模式

在處理異步操作時,有很多例子讓他們就像處理同步代碼一樣。如果使用 Promise 或 callbacks 來解決問題時需要使用很復雜的模式或者外部庫。

當需要再循環中使用異步獲取數據或使用 if-else 條件時就是一種很復雜的情況。

指數回退機制

使用 Promise 實現回退邏輯相當笨拙

function requestWithRetry (url, retryCount) { if (retryCount) { return new Promise((resolve, reject) => {  const timeout = Math.pow(2, retryCount)  setTimeout(() => {  console.log('Waiting', timeout, 'ms')  _requestWithRetry(url, retryCount)   .then(resolve)   .catch(reject)  }, timeout) }) } else { return _requestWithRetry(url, 0) }}function _requestWithRetry (url, retryCount) { return request(url, retryCount) .catch((err) => {  if (err.statusCode && err.statusCode >= 500) {  console.log('Retrying', err.message, retryCount)  return requestWithRetry(url, ++retryCount)  }  throw err })}requestWithRetry('http://localhost:3000') .then((res) => { console.log(res) }) .catch(err => { console.error(err) })            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 通许县| 昌乐县| 冕宁县| 方城县| 平凉市| 金溪县| 临沭县| 利津县| 调兵山市| 共和县| 新野县| 西宁市| 馆陶县| 玛沁县| 乐平市| 长乐市| 河西区| 师宗县| 江都市| 灵武市| 黄冈市| 上杭县| 日喀则市| 台南县| 新津县| 增城市| 牙克石市| 格尔木市| 许昌市| 靖安县| 土默特右旗| 车致| 都匀市| 额济纳旗| 苍溪县| 车险| 衡阳市| 桃源县| 旌德县| 盐亭县| 仙居县|