express和koa框架他们的核心其实都是中间件,但是他们的中间件事实上,它们的中间件的执行机制是不同的,特别是针对某个中间件中包含异步操作时
举个例子:
const middleware1 = (req,res,next)=>{
req.message = 'aaa'
next()
res.end(req.message) // 'aaabbbccc'
}
const middleware2 = (req,res,next)=>{
req.message += 'bbb'
next()
}
const middleware3 = (req,res,next)=>{
req.message += 'ccc'
}
res.end(req.message)返回’aaabbbccc’,这是为啥呢??
因为它是从上往下执行,当执行到next的时候,它会重新进行匹配,因为第一个已经执行完了,但是res.end在next后面并没有被执行,所以直接执行第2个,然后依次当最后一个执行完了,然后原路返回,当执行到res.end时候,req.message里面就为’aaabbbccc’了
先来看express异步实现
const middleware1 = (req,res,next)=>{
req.message = 'aaa'
next()
res.end(req.message)
}
const middleware2 = (req,res,next)=>{
req.message += 'bbb'
next()
}
const middleware3 = (req,res,next)=>{
axios.get('').then((res)=>{
req.message += res.data //假如这个结果为ccc
})
}
此时res.end(req.message) 返回的是’aaabbb’,这是为啥?
当middleware3里面是异步的话,它不会管middleware3执行完没有,会直接向下执行,咋解决呢?
把req.message放到middleware3里面,axios后面即可
但是我们就想在middleware1里面获取res.message咋办?
那你如果把middleware3当成一个中间件的话,就不好做了,就直接把它当成一个函数,在middleware1里面执行
express处理异步有点乏力,所以就有了koa
再来看koa同步实现
const middleware1 = (ctx,next)=>{
ctx.message = 'aaa';
next()
ctx.body = ctx.message //'aaabbbccc'
}
const middleware2 = (ctx,next)=>{
ctx.message += 'bbb'
next()
}
const middleware3 = (ctx,next)=>{
ctx.message += 'ccc'
}
同步没啥区别,关键是异步
再来看koa异步实现
const middleware1 = async (ctx,next)=>{
ctx.message = 'aaa';
await next()
ctx.body = ctx.message //'aaabbbccc'
}
const middleware2 = async (ctx,next)=>{
ctx.message += 'bbb'
await next()
}
const middleware3 = (ctx,next)=>{
const result = await axios.get('')
ctx.message += result.data //假如为ccc
}
此时ctx.body为’aaabbbccc’,那是为什么呢?
因为在koa中,next它的原理其实是一个promise,这个看它的源码就可以知道,我们在前面加了await将它变成同步操作,会从上往下依次执行,有结果了才会接着进行