functioncompose(middleware) { returnfunction (context, next) { let index = -1 returndispatch(0) functiondispatch(i) { if (i <= index) returnPromise.reject(newError('next() called multiple times')) index = i let fn = middleware[i] if (i === middleware.length) fn = next if (!fn) returnPromise.resolve() try { returnPromise.resolve(fn(context, dispatch.bind(null, i + 1))) } catch (err) { returnPromise.reject(err) } } } }
一晃眼是看不明白的,我们需要先明白 middleware 是什么,即中间件数组,那它是怎么来的呢,构造器中有 this.middleware,谁使用到了—— use 方法
我们先跳出去先看 use 方法
use
1 2 3 4
use(fn) { this.middleware.push(fn) returnthis }
除去异常处理,关键是这两步,this.middleware 是一个数组,第一步往 this.middleware 中 push 中间件;第二步返回 this 让其可以链式调用,当初本人被面试如何做 promise 的链式调用,懵逼脸,没想到在这里看到了
functioncompose(middleware) { returnfunction (context, next) { let index = -1; returndispatch(0); functiondispatch(i) { if (i <= index) returnPromise.reject( newError('next() called multiple times'), ); index = i; let fn = middleware[i]; if (i === middleware.length) fn = next; if (!fn) returnPromise.resolve(); try { returnPromise.resolve(fn(context, dispatch.bind(null, i + 1))); } catch (err) { returnPromise.reject(err); } } }; }
执行 const fn = compose(this.middleware),即如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
const fn = function (context, next) { let index = -1 returndispatch(0) functiondispatch (i) { if (i <= index) returnPromise.reject(newError('next() called multiple times')) index = i let fn = middleware[i] if (i === middleware.length) fn = next if (!fn) returnPromise.resolve() try { returnPromise.resolve(fn(context, dispatch.bind(null, i + 1))) } catch (err) { returnPromise.reject(err) } } } }
执行 fn(),即如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
const fn = function (context, next) { let index = -1 returndispatch(0) functiondispatch (i) { if (i <= index) returnPromise.reject(newError('next() called multiple times')) index = i // index = 0 let fn = middleware[i] // fn 为第一个中间件 if (i === middleware.length) fn = next // 当弄到最后一个中间件时,最后一个中间件赋值为 fn if (!fn) returnPromise.resolve() try { returnPromise.resolve(fn(context, dispatch.bind(null, i + 1))) // 返回一个 Promise 实例,执行 递归执行 dispatch(1) } catch (err) { returnPromise.reject(err) } } } }