CNode

express中间件和koa中间件的区别

问答
Zzhuni发布于9 年前最后回复8 年前13 回复10008 浏览0 收藏

var express = require('express'); var app = express();

app.use(function middleware1(req, res, next) { console.log('middleware1 开始'); next(); console.log('middleware1 结束'); })

app.use(function middleware2(req, res, next) { console.log('middleware2 开始'); next(); console.log('middleware2 结束'); })

app.use(function middleware3(req, res, next) { console.log('middleware3 开始'); next(); console.log('middleware3 结束'); })

app.get('/', function (req, res) { res.send('Hello World!'); console.log('123456') });

app.listen(3000, function () { console.log('Example app listening on port 3000!'); });

最后的输出结果是 ➜ express-demo node app.js Example app listening on port 3000! middleware1 开始 middleware2 开始 middleware3 开始 123456 middleware3 结束 middleware2 结束 middleware1 结束

请问一下这个和koa的洋葱模型有区别吗??

查看回复

回复 (13)

A
atian25#1·9 年前

不要用同步 不要用同步 不要用同步

F
fengmk2#2·9 年前

你在controller里面加个异步操作看看? 自豪地采用 CNodeJS ionic

L
Lizhooh#3·9 年前

虽然结果是相似的。但是上面的代码实际上是这样,和 Koa 的*洋葱模型还是有区别的。

app.use(function middleware1(req, res, next) {
    console.log('middleware1 开始')
        // next()
        (function (req, res, next) {
            console.log('middleware2 开始')
                // next()
                (function (req, res, next) {
                    console.log('middleware3 开始')
                        // next()
                        (function handler(req, res, next) {
                            res.json({ a: 1 })
                            console.log('123456')
                        })()
                    console.log('middleware3 结束')
                })()
            console.log('middleware2 结束')
        })()
    console.log('middleware1 结束')
})
Z
zhuni#4·9 年前
引用 atian25不要用同步 不要用同步 不要用同步

@atian25 加上异步确实是不同了。想深入研究下其中的原理,请问下可以应该看些什么?

A
atian25#5·9 年前

看源码

M
MiYogurt#7·8 年前

@atian25 你是不是说的是全局的这种,一个中间件会被全局执行。 express 是基于 layer 的,每次进入 handle 都会拿到匹配的一个然后执行,也就是基于路由的匹配,而 koa 更纯粹,把 router 放在了 中间件上面,而通过 koa-mount 也可以实现类似的。你说的洋葱是这个? 那 express 只能说是有条件的小洋葱。

M
MiYogurt#9·8 年前

image.png

它这个包裹就等于

reurn (async () => fn(context, function next () {
return dispatch(i + 1)
})())
A
atian25#10·8 年前

想那么多没用,我提个需求,你们实现下就知道了:

  1. 在 middleware A 里面输出一个 result 如 hi, user
  2. 在 middleware 里面获取到前一个的 result,并转化为 json { result: 'hi, user' } 再输出。

这才是真实的业务场景。

M
MiYogurt#11·8 年前
var express = require('express')
var app = express()

app.use(async function middleware1(req, res, next) {
    console.log('middleware1 开始')
    res.state = await Promise.resolve({ some: 123 })
    next()
    return 2
    console.log('middleware1 结束')
})

app.use(async function middleware2(req, res, next) {
    console.log('middleware2 开始')
    console.log(next)
    console.log(res.state)
    res.state = JSON.stringify(res.state)
    next()
    console.log('middleware2 结束')
})

app.use(function middleware3(req, res, next) {
    console.log('middleware3 开始')
    console.log(typeof res.state)
    next()
    console.log('middleware3 结束')
})

app.get('/', async function(req, res) {
    const ret = await Promise.resolve('Hello World!')
    res.send(ret)
    console.log(ret)
})

app.listen(3000, function() {
    console.log('Example app listening on port 3000!')
})

递归与回调而已,其实把 next 用 promise 包裹一下行了,const handle = async (...args) => next(...args) 就是了

https://nodelover.me/course/middleware/2

koa v1 多了一个执行器co而已 koa v2 async 自带执行器。

M
MiYogurt#13·8 年前

@atian25 没有,我是说 express 的 next 是回调 不是 promise。 express 也可以异步啊,只要在完成的时候 next 就行。

参与回复
登录后即可参与回复。登录