标签:function compose return 递归 koa middleware 中间件 next 源码
koa-compose是koa中间件的核心部分, 控制着中间件的执行流程, 造就了经典的洋葱模型。module.exports = compose function compose(middleware) { //首先是参数类型检查,不符合就抛错 //middleware必须是数组 if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!') //middleware的项必须是函数 for (const fn of middleware) { if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!') } // 返回一个闭包, 保持对 middleware 的引用 return function(context, next) { let index = -1 //从中间件第一项开始,执行中间件函数 return dispatch(0) function dispatch(i) { //索引小于等于index,说明一个中间件函数中next被调用多次,不允许 if (i <= index) return Promise.reject(new Error('next() called multiple times')) //index更新为i,对应前面的检测 index = i //取出中间件中的第i个函数 let fn = middleware[i] //如果索引到数组最后,函数变成next,不明白??? if (i === middleware.length) fn = next //遍历结束,fn为undefined,返回Promise,方便后面thenable if (!fn) return Promise.resolve() try { //关键部分,fn中传入context和next函数,对应于app.use((ctx,next) => {...})的用法 //Promise.resolve让返回值支持thenable调用 return Promise.resolve(fn(context, function next() { //尾递归dispatch,索引加1,不断调用中间件的下一个函数,直至用尽 //尾递归可以提升效率,缩短call Stack //递归是洋葱模型的关键,递归本身的call Stack就是按照洋葱模型来执行 //next之前执行代码,在next时候调用下一个中间件,下一个中间件继续执行next之前代码,next执行下下个中间件 //等到递归完成,到最后一个中间件,开始出栈,先执行最里面的next之后的代码,以此往外执行,形成洋葱调用 return dispatch(i + 1) })) } catch (err) { //如果递归调用中抛错,就reject return Promise.reject(err) } } } }
标签:function,compose,return,递归,koa,middleware,中间件,next,源码 来源: https://www.cnblogs.com/mengff/p/12857386.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。