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