express和koa2的运行机制差异
发布于 5 年前 作者 342450024 4551 次浏览 来自 问答

express 的中间件也可以形成“洋葱圈”模型,在 next 调用后写的代码同样会执行到,不过express中一般不会这么做,因为 express的response一般在最后一个中间件,那么其它中间件 next() 后的代码已经影响不到最终响应结果了 求大佬解释一下 这句话什么意思?

3 回复

我的理解是洋葱模型针对的是一次请求,也就是一次请求贯穿所有的中间件,express中可以通过res.end()返回一次请求,但是koa中即使ctx.body,也会等到所有中间件执行完毕后返回请求。可以看一下koa的处理代码, handleRequest(ctx, fnMiddleware) { const res = ctx.res; res.statusCode = 404; const onerror = err => ctx.onerror(err); //错误处理 const handleResponse = () => respond(ctx); //请求响应函数 onFinished(res, onerror); //监听response响应完成后,做资源清理工作 return fnMiddleware(ctx).then(handleResponse).catch(onerror); // fnMiddleware 返回Promise Promise.catch 捕获错误 }

都是回调写法,只是express写死了router里面加一层 而 koa2可以通过middleware无限串起来 这样导致同样的业务 koa2在middleware膨胀得情况下,性能要比express低

koa运行原理

/**
*middleware   数组
*/
const compose = async (middleware)=>{
    if(!Array.isArray(middleware)){
        throw new TypeError('Middleware stack must be an Array!')
    }
   return async (ctx,next)=>{
    let index = 0
    await dispatch(0)
    async function dispatch(i){
         if(index > i){
           throw new Error('next() called multiple times')
         }
         index  = i 
         let fn = middleware[i]
         if(i === middleware.length){
             fn = next 
         }
         if(fn){
              try{
                await fn(ctx,async ()=>dispatch(i+1))
              }catch(err){
                  console .error(err)
                  ctx.throw(500,'server error')
              }
         }
     }
   }
}

module.exports =compose

回到顶部