express 的中间件也可以形成“洋葱圈”模型,在 next 调用后写的代码同样会执行到,不过express中一般不会这么做,因为 express的response一般在最后一个中间件,那么其它中间件 next() 后的代码已经影响不到最终响应结果了 求大佬解释一下 这句话什么意思?
我的理解是洋葱模型针对的是一次请求,也就是一次请求贯穿所有的中间件,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
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
我的理解是洋葱模型针对的是一次请求,也就是一次请求贯穿所有的中间件,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运行原理