i作为该函数的参数,用于获取到当前下标的中间件。在上面的dispatch(0)传入了0,用于获取middleware[0]中间件。
来看看dispatch(i)这个函数都做了什么事
首先显示判断i<==index,如果true的话,则说明next()方法调用多次。为什么可以这么判断呢?等我们解释了所有的逻辑后再来回答这个问题。
接下来将当前的i赋值给index,记录当前执行中间件的下标,并对fn进行赋值,获得中间件。
index=i;
letfn=middleware[i]
获得中间件后,怎么使用?
try{
returnPromise.resolve(fn(context,functionnext(){
returndispatch(i+1)
}))
}catch(err){
returnPromise.reject(err)
}
dispatch(i)怎么执行
上面的代码执行了中间件fn(context,next),并传递了context和next函数两个参数。context就是koa中的上下文对象context。至于next函数则是返回一个dispatch(i+1)的执行结果。值得一提的是i+1这个参数,传递这个参数就相当于执行了下一个中间件,从而形成递归调用。
这也就是为什么我们在自己写中间件的时候,需要手动执行
awaitnext()
只有执行了next函数,才能正确得执行下一个中间件。
因此每个中间件只能执行一次next,如果在一个中间件内多次执行next,就会出现问题。回到前面说的那个问题,为什么说通过i<=index就可以判断next执行多次?
总之。因为正常情况下index必定会小于等于i。如果在一个中间件中调用多次next,会导致多次执行dispatch(i+1)。从代码上来看,每个中间件都有属于自己的一个闭包作用域,同一个中间件的i是不变的,而index是在闭包作用域外面的。