溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

express與koa的區(qū)別是什么

發(fā)布時間:2021-03-29 17:06:19 來源:億速云 閱讀:179 作者:Leah 欄目:web開發(fā)

express與koa的區(qū)別是什么?針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

connect的執(zhí)行流程
通常我們都說connect的中間件模型是線性的, 也就是一個一個往下執(zhí)行的, 如下圖:

express與koa的區(qū)別是什么

這么說當(dāng)然是沒錯的, 但是當(dāng)我們執(zhí)行下面代碼的時候可能會有那么一點小小的困惑:

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)我們訪問http://127.0.0.1:8080的時候, 控制臺會打印如下:

m1
m2
m3
m2 end
m1 end

這么個結(jié)果跟我們上面的模型似乎有點出入, 不是說線性的嗎, 為什么next后面的代碼還會繼續(xù)執(zhí)行? 當(dāng)然這個我們再之前已經(jīng)有過結(jié)論了, 有興趣的可以詳細(xì)瞧瞧, 我們現(xiàn)在直接拿來結(jié)果, connect的中間件模型偽代碼表示如下:

http.createServer(function (req, res) {
 m1 (req, res) {
 m2 (req, res) {
 m3 (req, res) {}
 }
 }
})

可以看到就是一層一層嵌套的回調(diào), 那么再把我們之前有點疑問的代碼簡化一下:

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')
})

千萬別被上面的回調(diào)繞暈了, 就是很簡單的回調(diào)函數(shù), 一切都解釋的通了: 即使res.end之后, 我們的代碼還是要繼續(xù)往下走的, 可以這么說connect的中間件其實也是洋蔥形的, 但是因為作為同步代碼, 一般不回這么做罷了, 那么上面我們可以重現(xiàn)描述一下connect的中間件模型了:

express與koa的區(qū)別是什么

Koa的執(zhí)行流程

同樣我們再Koa源碼分析, 也是說過Koa的中間件模型: 洋蔥形

express與koa的區(qū)別是什么

以下面代碼為例:

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ù), 輸出:

m1
m2
m3
m2 end
m1 end

emm 貌似跟connect沒差別, 之前看過一篇文章, 實驗到這里得到了一個koa和express的中間件模型沒差別的結(jié)論, 包括我也是很迷惑, 當(dāng)然是有差別的, 結(jié)論后面講. 同樣這里直接拿出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理所當(dāng)然的被'同步'了, 也就是說console.log(m3 end)的一切異步操作都可以'同步化'.

結(jié)論

說出結(jié)論之前我們其實可以想一下, 既然connect的中間件也是洋蔥形的, 那么跟koa一樣的用法似乎也沒啥毛病, 那么我來設(shè)想一下, 我們的服務(wù)需要取數(shù)據(jù)庫里的的一個用戶假設(shè)是getUser吧, getUser當(dāng)然是異步的. 分別來看看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
})

關(guān)于express與koa的區(qū)別是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI