# 实现一个中间件

## 用途

用于功能拆分,实现流水线

## 代码

```js
class MiddleWare {
  constructor() {
    this.init()
  }
  init () {
    this.allFn = []
  }
  // 将fn丢入数组
  use (fn) {
    this.allFn.push(fn)
  }
  // 执行函数，挨个执行数组中的fn
  run (ctx = {a: 'test'}, last = () => { console.log('middleware end') }) {
    const that = this
    let idx = -1   // -1表示当前未执行任何中间件
    return dispatch(0) // 触发第1个中间件
    function dispatch (i) {
      idx = i    // 设置当前下标
      let fn = that.allFn[i] || last  
      try {
        // 执行当前中间件的时候，给当前参数中的next参数赋值为一个函数，在这个函数中执行下个中间件
        if (fn) fn(ctx, () => {
          dispatch(i + 1)   // 触发下一个中间件，将下标+1
        })
      } catch (err) { // 所有的中间件执行完毕，执行回调
        last(ctx)
      }
    }
  }
}

export { MiddleWare }
```

## 参考

1. [Node.js 的中间件是用来做什么的，里面的 next() 是干什么的？](https://www.zhihu.com/question/37693420)
2. [从头实现一个koa框架](https://zhuanlan.zhihu.com/p/35040744)
3. [深入浅出node中间件原理](https://juejin.cn/post/6891126082200993805)
4. [Koajs中间件之next（二）](https://segmentfault.com/a/1190000015951113)
