最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Koa和Express的區(qū)別

 更新時間:2026年06月20日 09:11:27   作者:MariaH  
本文主要介紹了淺談Koa和Express的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前置核心概念

  1. Express:線性瀑布式中間件模型,基于回調,無原生 async/await 支持;
  2. Koa2:洋蔥圈中間件模型,基于 async/await + compose,原生支持異步;
  3. 同步:代碼無定時器、IO、數據庫、Promise;
  4. 異步:定時器、文件讀寫、數據庫、網絡請求、Promise、async 函數。

統一測試需求:
3 層中間件,要求:

  • 中間件1:前置拼接 a,后置輸出最終結果
  • 中間件2:拼接 b
  • 中間件3:拼接 c
    最終在中間件1后置打印 message = abc

一、同步場景:Express vs Koa(無異步操作)

1. Express 同步中間件

const express = require('express')
const app = express()

app.use((req, res, next) => {
  req.msg = 'a'
  console.log('Express 中間件1 前置')
  next()
  // next之后的代碼,所有下游中間件執(zhí)行完才執(zhí)行
  console.log('Express 中間件1 后置:', req.msg)
})

app.use((req, res, next) => {
  req.msg += 'b'
  console.log('Express 中間件2 前置')
  next()
  console.log('Express 中間件2 后置')
})

app.use((req, res) => {
  req.msg += 'c'
  console.log('Express 中間件3 執(zhí)行完畢')
  res.send(req.msg)
})

app.listen(3000)

執(zhí)行順序(同步無任何異步)

Express 中間件1 前置
Express 中間件2 前置
Express 中間件3 執(zhí)行完畢
Express 中間件2 后置
Express 中間件1 后置: abc

同步下 Express 特點

  1. 同步代碼下,執(zhí)行流程和Koa洋蔥模型表現一致;
  2. next() 是同步跳轉,會立刻執(zhí)行下一個中間件;
  3. next() 后面代碼會等所有下游中間件全部走完再回頭執(zhí)行;
  4. 同步場景二者行為幾乎無差異。

2. Koa 同步中間件

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

app.use((ctx, next) => {
  ctx.msg = 'a'
  console.log('Koa 中間件1 前置')
  next()
  console.log('Koa 中間件1 后置:', ctx.msg)
})

app.use((ctx, next) => {
  ctx.msg += 'b'
  console.log('Koa 中間件2 前置')
  next()
  console.log('Koa 中間件2 后置')
})

app.use(ctx => {
  ctx.msg += 'c'
  console.log('Koa 中間件3 執(zhí)行完畢')
  ctx.body = ctx.msg
})

app.listen(8000)

輸出順序和Express完全一致

Koa 中間件1 前置
Koa 中間件2 前置
Koa 中間件3 執(zhí)行完畢
Koa 中間件2 后置
Koa 中間件1 后置: abc

同步場景小結

同步代碼時,Express 和 Koa 表現完全相同
自上而下執(zhí)行 next() 前代碼,全部走完后,自下而上執(zhí)行 next() 后代碼。
差異只在異步場景爆發(fā)。

二、異步場景:Express(巨大缺陷)vs Koa(完美可控)

場景設定:中間件2中加入異步延時操作(模擬數據庫/接口請求)

// 模擬異步IO
function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time))
}

1. Express 異步中間件(重大問題)

const express = require('express')
const app = express()

app.use((req, res, next) => {
  req.msg = 'a'
  console.log('Express 中間件1 前置')
  next()
  // 異步導致此處提前執(zhí)行,拿不到完整abc
  console.log('Express 中間件1 后置:', req.msg)
})

app.use(async (req, res, next) => {
  req.msg += 'b'
  console.log('Express 中間件2 前置')
  // 異步延時2秒
  await sleep(2000)
  next()
  console.log('Express 中間件2 后置')
})

app.use((req, res) => {
  req.msg += 'c'
  console.log('Express 中間件3 執(zhí)行完畢')
  res.send(req.msg)
})

app.listen(3000)

執(zhí)行輸出順序(錯誤)

Express 中間件1 前置
Express 中間件2 前置
Express 中間件1 后置: a  // 重點:異步阻塞前直接回頭執(zhí)行后置!
// 等待2秒后
Express 中間件3 執(zhí)行完畢
Express 中間件2 后置

問題分析

  1. Express 不識別 async/await,next() 調用后直接同步返回,不會等待異步代碼完成;
  2. 中間件2內部 await sleep 阻塞時,事件循環(huán)讓出,Express 直接回到中間件1執(zhí)行 next() 后面的代碼;
  3. 中間件1后置代碼提前執(zhí)行,req.msg 只有 a,拿不到最終拼接結果;
  4. 無法實現“等所有下游邏輯完成再執(zhí)行后置”的需求。

Express 異步解決方案(丑陋)

必須手動在異步結束后調用 next(),強行嵌套回調,回調地獄:

app.use((req, res, next) => {
  req.msg += 'b'
  console.log('中間件2 前置')
  setTimeout(() => {
    req.msg += '延遲b'
    next() // 異步完成后再放行
  }, 2000)
})

缺點:多層異步會無限嵌套,流程不可讀、難以維護。

2. Koa 異步中間件(原生支持,流程不亂)

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

function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time))
}

app.use(async (ctx, next) => {
  ctx.msg = 'a'
  console.log('Koa 中間件1 前置')
  await next() // 等待所有下游中間件全部執(zhí)行完成才往下走
  console.log('Koa 中間件1 后置:', ctx.msg)
})

app.use(async (ctx, next) => {
  ctx.msg += 'b'
  console.log('Koa 中間件2 前置')
  await sleep(2000) // 異步阻塞,不會跳出當前中間件
  await next()
  console.log('Koa 中間件2 后置')
})

app.use(ctx => {
  ctx.msg += 'c'
  console.log('Koa 中間件3 執(zhí)行完畢')
  ctx.body = ctx.msg
})

app.listen(8000)

正確輸出順序

Koa 中間件1 前置
Koa 中間件2 前置
// 等待2秒
Koa 中間件3 執(zhí)行完畢
Koa 中間件2 后置
Koa 中間件1 后置: abc

Koa 異步核心原理

  1. Koa 使用 compose 組合中間件,所有中間件被包裝成 Promise 調用鏈;
  2. await next() 會暫停當前中間件,完整等待下游所有中間件(含異步)全部執(zhí)行完畢,才恢復當前中間件剩余代碼;
  3. 無論中間件內部有多少層異步、定時器、數據庫操作,洋蔥模型執(zhí)行順序永遠穩(wěn)定不變;
  4. 無回調嵌套,線性代碼書寫復雜異步流程。

三、同步/異步場景完整異同對照表

1. 相同點

同步代碼場景

  • 兩者執(zhí)行順序完全一致:自上而下前置 → 自下而上后置;
  • next() 同步跳轉,下游全部執(zhí)行完再回頭執(zhí)行后置邏輯;
  • 簡單同步接口(無數據庫/文件)表現無區(qū)別。

基礎能力一致

  • 都基于 Node http 模塊封裝;
  • 都依靠中間件處理請求;
  • 都支持多層中間件堆疊。

2. 不同點(分同步、異步區(qū)分)

維度ExpressKoa2
同步執(zhí)行邏輯線性流轉,next后代碼后置執(zhí)行洋蔥流轉,和Express同步表現一致
異步執(zhí)行邏輯next() 同步返回,不會等待異步;異步阻塞會直接跳出當前中間件,后置代碼提前執(zhí)行,流程錯亂await next() 阻塞等待全部下游異步完成,洋蔥順序永久穩(wěn)定
異步語法支持原生不支持async/await,需回調嵌套,極易產生回調地獄原生基于Promise+async/await,無嵌套
中間件底層實現數組順序遍歷,線性瀑布模型compose遞歸調用,Promise鏈式洋蔥模型
上下文對象req、res分離,全局掛載數據容易沖突統一ctx上下文,一次請求獨立ctx,數據隔離
異步錯誤捕獲異步內部拋出錯誤無法被全局錯誤捕獲,必須手動try/catch傳err給next(err)全局可捕獲async中間件拋出的錯誤,統一error事件處理
多異步串聯多層異步必須嵌套,可讀性極差平鋪書寫,await順序執(zhí)行,邏輯清晰

四、異步錯誤處理對比(補充關鍵差異)

Express 異步錯誤捕獲缺陷

app.use(async (req, res, next) => {
  // 異步拋出錯誤,Express 捕獲不到,直接崩潰
  throw new Error('數據庫查詢失敗')
  next()
})

解決方式:必須手動 try/catch + next(err)

app.use(async (req, res, next) => {
  try {
    await sleep(1000)
    throw new Error('異常')
  } catch (err) {
    next(err) // 手動傳遞錯誤
  }
})
// 錯誤中間件接收
app.use((err, req, res, next) => {
  res.status(500).send(err.message)
})

Koa 異步錯誤天然支持

app.use(async (ctx, next) => {
  await sleep(1000)
  throw new Error('數據庫異常')
})
// 全局統一捕獲,無需手動傳遞
app.on('error', (err, ctx) => {
  ctx.status = 500
  ctx.body = { msg: err.message }
})

所有 async 中間件拋出的異常都會被 Koa 內部 Promise 捕獲,自動觸發(fā)全局 error 事件。

五、總結核心結論

只寫同步代碼:Express 和 Koa 幾乎沒有區(qū)別,洋蔥/瀑布執(zhí)行效果一樣;

項目存在大量異步(數據庫、Redis、文件、接口) :二者出現本質鴻溝:

  • Express:異步會打亂中間件執(zhí)行順序,回調嵌套、錯誤處理繁瑣;
  • Koa:依靠 await next() 固定洋蔥執(zhí)行流,異步代碼平鋪書寫,錯誤統一捕獲;

核心根源:
Express 中間件只是普通回調函數,無 Promise 封裝;
Koa 通過 compose 將所有中間件包裝成 Promise 調用鏈,讓異步流程可控。

到此這篇關于淺談Koa和Express的區(qū)別的文章就介紹到這了,更多相關Koa和Express區(qū)別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • async/await優(yōu)雅的錯誤處理方法總結

    async/await優(yōu)雅的錯誤處理方法總結

    這篇文章主要給大家介紹了關于async/await優(yōu)雅的錯誤處理方法的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-01-01
  • node中的cookie的具體使用

    node中的cookie的具體使用

    這篇文章主要介紹了node中的cookie的具體使用,詳細的介紹了什么是cookie和cookie的使用,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • 使用命令行升級Node.js的版本的操作指南

    使用命令行升級Node.js的版本的操作指南

    這篇文章主要給大家介紹了關于如何使用命令行升級Node.js的版本的操作指南,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧
    2023-11-11
  • 詳解用node-images 打造簡易圖片服務器

    詳解用node-images 打造簡易圖片服務器

    本篇文章主要介紹了詳解用node-images 打造簡易圖片服務器,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 利用Chrome DevTools直接調試Node.js和JavaScript的方法詳解(并行)

    利用Chrome DevTools直接調試Node.js和JavaScript的方法詳解(并行)

    現在我們可以用瀏覽器調試node.js了!!!下面這篇文章主要介紹了利用Chrome DevTools直接調試Node.js和JavaScript的方法步驟,文中介紹的很詳細,需要的朋友可以參考學習,下面來一起看看吧。
    2017-02-02
  • Node.js使用對話框ngDialog的示例代碼

    Node.js使用對話框ngDialog的示例代碼

    本篇文章主要介紹了Node.js使用對話框ngDialog的示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • 在linux中使用包管理器安裝node.js

    在linux中使用包管理器安裝node.js

    這篇文章主要介紹了在linux中使用包管理器安裝node.js的方法以及具體安裝過程,非常詳細,推薦給大家,有需要的小伙伴參考下吧。
    2015-03-03
  • node.js中的fs.fsync方法使用說明

    node.js中的fs.fsync方法使用說明

    這篇文章主要介紹了node.js中的fs.fsync方法使用說明,本文介紹了fs.fsync的方法說明、語法、接收參數、使用實例和實現源碼,需要的朋友可以參考下
    2014-12-12
  • 如何在Node和瀏覽器控制臺中打印彩色文字

    如何在Node和瀏覽器控制臺中打印彩色文字

    這篇文章主要介紹了如何在Node和瀏覽器控制臺中打印彩色文字,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • express搭建的nodejs項目使用webpack進行壓縮打包

    express搭建的nodejs項目使用webpack進行壓縮打包

    對于打包這個問題它并不是難點,但是對于我們這種初學者來說,根本就不知道應該怎么做,下面這篇文章主要給大家介紹了關于express搭建的nodejs項目使用webpack進行壓縮打包的相關資料,需要的朋友可以參考下
    2022-12-12

最新評論

筠连县| 阳新县| 息烽县| 姜堰市| 从江县| 铜陵市| 鹤峰县| 精河县| 安图县| 通河县| 丹东市| 平遥县| 彰化市| 隆化县| 南安市| 邹城市| 巴东县| 苍山县| 阳高县| 永昌县| 清涧县| 金乡县| 云林县| 商丘市| 顺昌县| 资中县| 苍南县| 盖州市| 京山县| 杨浦区| 定南县| 蒙山县| 公主岭市| 陈巴尔虎旗| 临武县| 日照市| 华坪县| 建宁县| 西峡县| 兴山县| 井冈山市|