摘要:以前其實寫過一篇和的對比但是后來發現里面有不少謬誤所以一直惦記著糾正一下之前的錯誤尤其關于中間件部分的對比這里的就拿更加簡單的代替的執行流程通常我們都說的中間件模型是線性的也就是一個一個往下執行的如下圖這么說當然是沒錯的但是當我們執行下面代
以前其實寫過一篇express和koa的對比, 但是后來發現里面有不少謬誤. 所以一直惦記著糾正一下之前的錯誤, 尤其關于中間件部分的對比.
這里的express就拿更加簡單的connect代替
connect的執行流程通常我們都說connect的中間件模型是線性的, 也就是一個一個往下執行的, 如下圖:
這么說當然是沒錯的, 但是當我們執行下面代碼的時候可能會有那么一點小小的困惑:
const connect = require("connect") const app = connect() app.use(function m1 (req, res, next) { console.log("m1") next() console.log("m1 end") }) app.use(function m2 (req, res, next) { console.log("m2") next() console.log("m2 end") }) app.use(function m3 (req, res, next) { console.log("m3") res.end("hello") }) app.listen(8080)
當我們訪問http://127.0.0.1:8080的時候, 控制臺會打印如下:
m1 m2 m3 m2 end m1 end
這么個結果跟我們上面的模型似乎有點出入, 不是說線性的嗎, 為什么next后面的代碼還會繼續執行? 當然這個我們再之前已經有過結論了, 有興趣的可以詳細瞧瞧, 我們現在直接拿來結果, connect的中間件模型偽代碼表示如下:
http.createServer(function (req, res) { m1 (req, res) { m2 (req, res) { m3 (req, res) {} } } })
可以看到就是一層一層嵌套的回調, 那么再把我們之前有點疑問的代碼簡化一下:
http.createServer(function (req, res) { console.log("m1") m1 (req, res) { console.log("m2") m2 (req, res) { m3 (req, res) { console.log("m3") res.end("hello") } } console.log("m2 end") } console.log("m1 end") })
千萬別被上面的回調繞暈了, 就是很簡單的回調函數, 一切都解釋的通了: 即使res.end之后, 我們的代碼還是要繼續往下走的, 可以這么說connect的中間件其實也是洋蔥形的, 但是因為作為同步代碼, 一般不回這么做罷了, 那么上面我們可以重現描述一下connect的中間件模型了:
Koa的執行流程同樣我們再Koa源碼分析, 也是說過Koa的中間件模型: 洋蔥形
以下面代碼為例:
const Koa = require("koa") const app = new Koa() app.use(async function m1 (ctx, next) { console.log("m1") await next() console.log("m1 end") }) app.use(async function m2 (ctx, next) { console.log("m2") await next() console.log("m2 end") }) app.use(async function m3 (ctx) { console.log("m3") ctx.body = "hello" }) app.listen(8080)
訪問服務, 輸出:
m1 m2 m3 m2 end m1 end
emm 貌似跟connect沒差別, 之前看過一篇文章, 實驗到這里得到了一個koa和express的中間件模型沒差別的結論, 包括我也是很迷惑, 當然是有差別的, 結論后面講. 同樣這里直接拿出koa中間件的簡化模型:
Promise.resolve(async m1 () { console.log(m1) await Promise.resolve(async m2 () { console.log(m2) await Promise.resolve(async m3 () { console.log(m3) ctx.body = "xxx" }) console.log(m2 end) }) console.log(m1 end) })
我們知道async/await的作用是"同步化"異步操作(看上去如此, 其實不是, 但是我們不需要去管), 那這里的Promise理所當然的被"同步"了, 也就是說console.log(m3 end)的一切異步操作都可以"同步化".
結論說出結論之前我們其實可以想一下, 既然connect的中間件也是洋蔥形的, 那么跟koa一樣的用法似乎也沒啥毛病, 那么我來設想一下, 我們的服務需要取數據庫里的的一個用戶假設是getUser吧, getUser當然是異步的. 分別來看看connect和koa的做法吧:
// connect app.use(function (req, res) { getUser(user => res.end(user)) }) // Koa app.use(async (ctx) => { const user = await getUser() ctx.body = user })
當然這么看似乎沒啥差別. 那直接給出結論吧(憋): connect的中間件是同步, 不會"等"其他異步操作, koa則可以"等"異步操作. 當然你不等也沒啥問題.
有啥問題可以互相交流哈.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92724.html
摘要:使用承諾和異步功能來擺脫回調地獄的應用程序,并簡化錯誤處理。它暴露了自己的和對象,而不是的和對象。因此,可被視為的模塊的抽象,其中是的應用程序框架。這使得中間件對于整個堆棧而言不僅僅是最終應用程序代碼,而且更易于書寫,并更不容易出錯。 Koa 與 Express 此系列文章的應用示例已發布于 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新...
摘要:前言目前最新版本是所以本文分析也基于這個版本。源碼分析直接切入主題由于目前是一個獨立的路由和中間件框架。所以分析的方向也以這兩個為主。源碼去年的時候有分析過現在對比分析思考下。 前言 目前express最新版本是4.16.2,所以本文分析也基于這個版本。目前從npm倉庫上來看express使用量挺高的,express月下載量約為koa的40倍。所以目前研究下express還是有一定意義...
摘要:我們分別使用這樣的原則來測試向每個架構注入個靜態路由,測試最末尾的那個。而我們如何做到達到的性能,主要我們在內存中維護了一份靜態路由列表,能讓程序以最快的速度找到我們需要的。 對比 如果使用nodejs來搭建Service服務,那么我們首選express或者koa,而fastify告訴我們一個數據: Framework Version Router? Requests/sec ...
摘要:本文是年框架回顧系列的最后的一篇文章,主要介紹的后端框架情況。葡萄城公司成立于年,是全球領先的集開發工具商業智能解決方案管理系統設計工具于一身的軟件和服務提供商。 本文是2017年 JavaScript 框架回顧系列的最后的一篇文章,主要介紹 JavaScript 的后端框架情況。 showImg(https://segmentfault.com/img/bV2TPd?w=735&h=...
摘要:掘金原文地址譯文出自掘金翻譯計劃譯者請持續關注中文維護鏈接獲取最新內容。由于以下的瀏覽器市場份額已逐年下降,所以對于瀏覽器技巧三視覺效果前端掘金揭秘學習筆記系列,記錄和分享各種實用技巧,共同進步。 沉浸式學 Git - 前端 - 掘金目錄 設置 再談設置 創建項目 檢查狀態 做更改 暫存更改 暫存與提交 提交更改 更改而非文件 歷史 別名 獲得舊版本 給版本打標簽 撤銷本地更改... ...
閱讀 3603·2021-11-24 10:25
閱讀 2508·2021-11-24 09:38
閱讀 1217·2021-09-08 10:41
閱讀 2904·2021-09-01 10:42
閱讀 2569·2021-07-25 21:37
閱讀 1981·2019-08-30 15:56
閱讀 914·2019-08-30 15:55
閱讀 2750·2019-08-30 15:54