koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用,经过组合不一样的 generator,能够免除重复繁琐的回调函数嵌套,并极大地提高错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得驾轻就熟。git
koa自己相较于其余web框架来讲更轻量。可是若是要实现更健壮的服务,咱们就须要添加大量的中间件来丰富咱们的服务! 因此对比其余web框架,koa有本身独特的处理中间件的方式-->compose!github
compose的源码并很少,二十几行,那它是如何实现你们所认为的洋葱模型呢web
探索源码前咱们先定义下当前的场景,以便于更好的描述数组
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) => {
console.log(1);
await next();
console.log(1.1)
})
app.use(async (ctx, next) => {
console.log(2)
await next();
console.log(2.1)
})
app.use(async (ctx, next) => {
console.log(3)
await next();
console.log(3.1)
})
app.listen(8080, () => {
console.log('8080')
})
// 输出结果 1-->2-->3-->3.1-->2.1-->1.1
复制代码
源码地址bash
// 这是我简化一部分异常处理后的源码
// middleware 为存放中间件函数的数组
function compose (middleware) {
return function (context, next) {
let index = -1
return dispatch(0)
function dispatch (i) {
index = i
let fn = middleware[i]
if (i === middleware.length) fn = next
if (!fn) return Promise.resolve()
return Promise.resolve(fn(context, function next () {
return dispatch(i + 1)
}))
}
}
}
复制代码
分析调用的过程:app
我这里实现了一个简单版的中间件处理逻辑,根据这个帮咱们更好的去理解compose框架
function compose(middleware) {
dispatch(0);
function dispatch(idx) {
middleware[idx](ctx, () => dispatch(idx + 1));
}
}
复制代码
听过上述的分析,相信你们对Koa的中间件处理有了必定的认识;看起来Koa的中间件处理就是一个洋葱模型,可是在某种状况下,可能这个洋葱模型是不完整,由于有些时候程序不会走完整个中间件的处理,可能在第一个或中间某个中间就已经结束了。koa