首頁 web前端 js教程 Koa2中有關async&await的用法有哪些?

Koa2中有關async&await的用法有哪些?

Jun 07, 2018 pm 03:50 PM
async await koa2

這篇文章主要介紹了理解Koa2中的async&await的用法,現在分享給大家,也給大家做個參考。

Koa是一款非常著名的Node服務端框架,有1.x版本和2.x版本。前者使用了generator來進行非同步操作,後者則用了最新的async/await方案

#一開始使用這種寫法的時候,我遇到一個問題,程式碼如下:

const Koa = require('koa');
const app = new Koa();

const doSomething = time => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('task done!')
    }, time)
  })
}

// 用来打印请求信息
app.use((ctx, next) => {
  console.log(`${ctx.method}:::${ctx.url}`)
  next()
})

app.use(async ctx => {
  const result = await doSomething(3000)
  console.log(result);
  ctx.body = result
})

app.listen(3000);
登入後複製

讓我們測試一下:curl http://localhost:3000

期望結果:

(3秒後...)task done!

然而現實卻是:

(立即)
Not Found

什麼鬼?為什麼沒有按照預期執行?這就需要我們來理解下Koa中中間件是如何串連起來的了。翻一下原始碼,將middlewares串連起來的程式碼如下:

function compose (middleware) {
 return function (context, next) {
  // 这个index用来计数,防止next被多次调用
  let index = -1
  // 执行入口
  return dispatch(0)
  
  function dispatch (i) {
   // 如果next被多次调用,报异常
   if (i <= index) return Promise.reject(new Error(&#39;next() called multiple times&#39;))
   index = i
   // 取出第一个middleware
   let fn = middleware[i]
   // 将最初传入的next作为最后一个函数执行
   if (i === middleware.length) fn = next
   if (!fn) return Promise.resolve()
   try {
    /**
    这里就是关键了,Promise.resolve是什么意思呢?
     Promise.resolve方法有下面三种形式:
     
     Promise.resolve(value);
     Promise.resolve(promise);
     Promise.resolve(theanable);
     
    这三种形式都会产生一个新的Promise。其中:

    第一种形式提供了自定义Promise的值的能力,它与Promise.reject(reason)对应。两者的不同,在于得到的Promise的状态不同。

    第二种形式,提供了创建一个Promise的副本的能力。

    第三种形式,是将一个类似Promise的对象转换成一个真正的Promise对象。它的一个重要作用是将一个其他实现的Promise对象封装成一个当前实现的Promise对象。例如你正在用bluebird,但是现在有一个Q的Promise,那么你可以通过此方法把Q的Promise变成一个bluebird的Promise。第二种形式可以归在第三种里面
    
    **/
    return Promise.resolve(fn(context, function next () {
     // 执行下一个middleware,返回结果也是一个Promise
     return dispatch(i + 1)
    }))
   } catch (err) {
    return Promise.reject(err)
   }
  }
 }
}
登入後複製

有了以上基礎,我們再來看一下之前的問題,為什麼response沒有等到第二個middleware執行完成就立即返回了呢?

因為第一個middleware並不是一個非同步函數啊。

由於每次next方法的執行,實際上都是返回了一個Promise對象,所以如果我們在某個middleware中執行了異步操作,要想等待其完成,就要在執行這個middleware之前加入await

那我們來改寫一下之前的程式碼

app.use(async (ctx, next) => {
  console.log(`${ctx.method}:::${ctx.url}`)
  await next()
})

app.use(async ctx => {
  const result = await doSomething(3000)
  console.log(result);
  ctx.body = result
})
登入後複製

好了,沒有問題,一切如期望執行:clap:

錯誤處理

借助了Promise強大的功力,配合async/await語法,我們只需要把try/catch的操作寫在最外層的middleware中,就可以捕獲到之後所有中間件的異常!

app.use(async (ctx, next) => {
  try{
    await next()
  }catch(err){
    console.log(err)
  }
})

app.use(async (ctx)=>{
  throw new Error(&#39;something wrong!&#39;)
  ctx.body = &#39;Hello&#39;
})
登入後複製

基於中間件鏈的完全控制,並且基於 Promise 的事實使得一切都變得容易操作起來。不再是到處的 if (err) return next(err) 而只有 promise

上面是我整理給大家的,希望今後會對大家有幫助。

相關文章:

在D3.js中如何實作動態進度條

vue中實作模態方塊(通用寫法)

在Vue.js 2.0和Cordova開發中如何建構webApp環境

以上是Koa2中有關async&await的用法有哪些?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

async是es6還是es7的 async是es6還是es7的 Jan 29, 2023 pm 05:36 PM

async是es7的。 async和await是ES7中新增內容,是對於非同步操作的解決方案;async/await可以說是co模組和生成器函數的語法糖,用更清晰的語意解決js非同步程式碼。 async顧名思義是「非同步」的意思,async用於聲明一個函數是異步的;async和await有一個嚴格規定,兩者都離不開對方,且await只能寫在async函數中。

vue3+async-validator如何實作表單驗證 vue3+async-validator如何實作表單驗證 May 11, 2023 am 09:55 AM

搭建vue3的專案建立專案前這裡我們首先要說明的是,我們使用的版本狀況Nodejs:v17.5.0pnpm:7.0.0Vue:3.2.25首先我們Vite建立一個vue3的專案demo,名字就叫FormValidate,我們在命令列輸入命令pnpmcreateviteFormValidate回車然後選擇vue繼續回車,說明我們已經初步創建了FormValidate(表單驗證)項目根據命令行的提示,我們進入項目根目錄,然後使用命令pnpminstall安裝項目需要的依賴,當然這裡使用pnpm是比n

在Vue中如何使用async/await處理非同步操作 在Vue中如何使用async/await處理非同步操作 Jun 11, 2023 am 09:18 AM

在Vue中如何使用async/await處理非同步操作隨著前端開發的不斷發展,我們需要在Vue中處理更複雜的非同步操作。雖然Vue已經提供了很多便捷的方式來處理非同步操作,但是在某些情況下,我們可能需要使用更簡單、直覺的方式來處理這些非同步操作。這時候,async/await就成為了一個非常好的選擇。什麼是async/await?在ES2017中,async和

Python async模組如何使用 Python async模組如何使用 May 30, 2023 pm 11:43 PM

協程:協程(Coroutine),也可以稱為微線程,是一種使用者態內的上下文切換技術。簡而言之,其實就是透過一個執行緒實作程式碼區塊相互切換執行Python對協程的支援是透過generator實現的。在generator中,我們不但可以透過for迴圈來迭代,還可以不斷呼叫next()函數來取得由yield語句傳回的下一個值。但是Python的yield不但可以傳回一個值,它還可以接收呼叫者發出的參數。一、什麼是generator(生成器)在Python中,這種一邊循環一邊計算的機制,稱為生成器:gene

Python 中的協程,到底是怎麼回事? Python 中的協程,到底是怎麼回事? Apr 14, 2023 am 08:28 AM

一.傳統的Sync語法請求範例還是一樣, 在了解Async語法的實作之前, 先從一個Sync的語法範例開始, 現在假設有一個HTTP請求, 這個程式會透過這個請求取得對應的回應內容, 並列印出來, 程式碼如下:import socket def request(host: str) -&gt; None: """模擬請求並列印回應器""" url: str = f"http://{host}" sock

Nodejs中koa2怎麼連接mysql Nodejs中koa2怎麼連接mysql Jun 01, 2023 pm 12:40 PM

將查詢結果轉換為物件或陣列在真實開發中,實際上某些查詢結果應該放入到一個物件中JSON_OBJECT:()中是key-value的形式SELECTproducts.idasid,products.titleastitle,products.priceasprice,products .scoreasscore,JSON_OBJECT('id',brand.id,'name',brand.name,'rank&#

聊聊Node怎麼用async函數 聊聊Node怎麼用async函數 Dec 20, 2022 pm 09:16 PM

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

聊聊JS循環中使用await會產生什麼'化學反應” 聊聊JS循環中使用await會產生什麼'化學反應” Mar 02, 2023 pm 05:22 PM

這篇文章為大家帶來了關於JavaScript循環的相關知識,其中主要為大家聊聊在js循環中怎麼使用使用await以及結果分析,感興趣的朋友一起來看一下吧,希望對大家有幫助。

See all articles