app.use((ctx, next) => {
const start = new Date;
console.log('app 1')
return next().then(() => {
const ms = new Date - start;
console.log('app 1 callback')
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
});
app.use(async (ctx, next) => {
const start = new Date;
console.log('app 2')
await next();
const ms = new Date - start;
console.log('app 2 callback')
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
app.use(ctx => {
console.log('app 3')
ctx.body = "hello KOA";
});
app 1
app 2
app 3
app 2 callback
GET / - 3ms
app 1 callback
GET / - 7ms
刚开始学习 koa2 ,想问一下为什么 ctx.body = ‘xxx’ 会到最后才执行呢,它看起来明明就是一个同步方法,用 promise 理解也就是
return next().then(() => {
//
return next().then(() => {
//
return next().then(() => {
ctx.body = 'xxx'
// 那这一步应该会直接执行才对
})
})
})
ctx.body 的确是同步执行的啊,不太理解你的问题
ctx.body = "hello KOA";
这一句确实在console.log('app 3')
这一句后面执行的,不过在这里他只是一个赋值操作,会等到所有中间件都往回执行完后再返回给客户端,具体可以看看洋葱圈模型。
想知道为什么最后执行,你可以看下koa中间件的源代码,不多,绝对可以让你受益匪浅 自豪地采用 CNodeJS ionic
专业助攻
即使执行了ctx.body = 'hello Koa'
这一句.也没有立即返回,需要等待中间件都结束才可以.next的原理应该是类似递归,触发所有中间件之后才会会return Promise.resolve
.
@yudawei1230 就是准备看,找个时间研究下
@leemove 我就是不懂这一点,能稍微讲下么?
@feng-fu 为什么会等待所有中间件往回执行完呢?
支持
请求 ==>中间件1 ==> 中间件2 ==> 响应中间件 ==> 2中间件 ==> 1中间件 ==> 响应 洋葱模型 看看源码吧 不要一直问为什么 要自己去看 大家都知道为什么了那大家都可以去开发框架了
@hewentaowx 昨天刚看了一些,源码就是 compose 函数把中间件结合成一个递归表达式,等待最后一个 promise resolve,才会去返回/处理响应
其实很简单,ctx.body 仅仅是一个赋值操作,而把 ctx.body 的数据响应给客户端的实际上是所有中间件执行完毕后调用的 respond 函数,看下面的注释吧
callback() {
// compose 把中间件聚合成一个函数
const fn = compose(this.middleware);
if (!this.listeners('error').length) this.on('error', this.onerror);
const handleRequest = (req, res) => {
res.statusCode = 404;
const ctx = this.createContext(req, res);
const onerror = err => ctx.onerror(err);
// handleResponse 函数实际上调用的是 respond 函数
// respond 函数是真正将 ctx.body 赋值到的数据发送给客户端的地方
const handleResponse = () => respond(ctx);
onFinished(res, onerror);
// 中间件执行完毕后才执行处理响应的函数 handleResponse
return fn(ctx).then(handleResponse).catch(onerror);
};
return handleRequest;
}
以前写过一个 koa1 和 koa2 的 compose 加载器解析,koa 无论 1 还是 2 的核心都是这个 compose 方法 有兴趣可以看看 跨入Koa2.0,从Compose开始
@hyj1991 对,就是这样的,刚开始不太理解,以为直接赋值操作就会直接返回响应。肯定有兴趣看的,已收藏