koa中间件之compose

koa

koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用,经过组合不一样的 generator,能够免除重复繁琐的回调函数嵌套,并极大地提高错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得驾轻就熟。git

核心-compose

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

  • 一、取出middleware中的第一个中间件函数而且用Promise.resolve包装一下执行,执行的时候传入context上下文和next函数
  • 二、next的函数体内容实际就是调用第二个被Promise.resolve包装后的中间件函数,因此,当定义的中间函数调用next()方法的时候实际是去调用第二个中间件函数执行了,而且咱们发现,全部的中间件函数都是被包装在Promise.resolve中执行;因此咱们能够在中间件函数中 await next()
  • 三、当middle中最后一个中间件函数调用完毕后,根据代码从上往下执行的逻辑,会依次往前执行其余中间件next后边的代码
简单版实现compose

我这里实现了一个简单版的中间件处理逻辑,根据这个帮咱们更好的去理解compose框架

function compose(middleware) {
    dispatch(0);
    function dispatch(idx) {
        middleware[idx](ctx, () => dispatch(idx + 1));
    }
}
复制代码

结论

听过上述的分析,相信你们对Koa的中间件处理有了必定的认识;看起来Koa的中间件处理就是一个洋葱模型,可是在某种状况下,可能这个洋葱模型是不完整,由于有些时候程序不会走完整个中间件的处理,可能在第一个或中间某个中间就已经结束了。koa

相关文章
相关标签/搜索