本篇文章介绍的是compose
函数。
可能听起来有点懵圈?下面会一一道来:
在我们一般处理某个业务逻辑时,比如新增、删除、修改记录,在逻辑处理之前首先要校验一下用户的身份,处理完逻辑可能还得记录一下日志或者完成逻辑的耗时等等。这好办,我们直接将这些校验和日志添加到业务逻辑里就好了,这样肯定是不行了,代码冗余。有没有更好的办法呢?
这样就要提到中间件middleware
了。中间件的作用就是在请求前和请求后插入逻辑,代码得到复用。
那如何将中间件和请求组合起来执行呢?compose
这时候就登场了。这里以koa-compose
为例。
koa-compose
安装
$ npm install koa-compose
使用
import compose from "koa-compose"
fn = compose([a, b, c, ...])
传入异步函数数组。
源码
function compose (middleware) {if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')for (const fn of middleware) {if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')}/** * @param {Object} context * @return {Promise} * @api public */return function (context, next) {// last called middleware #let index = -1return dispatch(0)function dispatch (i) {if (i <= index) return Promise.reject(new Error('next() called multiple times'))index = ilet fn = middleware[i]if (i === middleware.length) fn = nextif (!fn) return Promise.resolve()try {return Promise.resolve(fn(context, dispatch.bind(null, i + 1)))} catch (err) {return Promise.reject(err)}}}
1.首先是参数校验,传入的必须是数组,其次每个数组的元素类型必须是函数
2.返回值是一个函数, 传入了两个参数,分别是context
和next
下一个执行的函数
3.返回的函数里声明了一个dispatch
函数,首先校验了next
多次调用
4.然后就是根据索引取到对应的中间件,通过Promise.resolve()
执行该中间件,next
传入下一个dispatch
。并返回resolve
,如果报错则返回Promise.reject(err)
,如果中间件执最后一个执行完毕,则返回Promise.resolve()
一个空的Promise
对象。
关联的设计模式(责任链模式)
为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到没有对象处理它为止。
结束语
它的核心逻辑在dispatch
函数里。每次等待上一个中间件执行完毕之后,就执行一个,链式调用,保证了异步函数按顺序执行。
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享