首页 > 语言 > JavaScript > 正文

傻瓜式解读koa中间件处理模块koa-compose的使用

2024-05-06 15:28:24
字体:
来源:转载
供稿:网友

最近需要单独使用到koa-compose这个模块,虽然使用koa的时候大致知道中间件的执行流程,但是没仔细研究过源码用起来还是不放心(主要是这个模块代码少,多的话也没兴趣去研究了)。

koa-compose看起来代码少,但是确实绕。闭包,递归,Promise。。。看了一遍脑子里绕不清楚。看了网上几篇解读文章,都是针对单行代码做解释,还是绕不清楚。最后只好采取一种傻瓜的方式:

koa-compose去掉一些注释,类型校验后,源码如下:

function compose (middleware) { return function (context, next) {  // last called middleware #  let index = -1  return dispatch(0)  function dispatch (i) {   if (i <= index) return Promise.reject(new Error('next() called multiple times'))   index = i   let fn = middleware[i]   if (i === middleware.length) fn = next   if (!fn) return Promise.resolve()   try {    return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));   } catch (err) {    return Promise.reject(err)   }  } }}

写出如下代码:

var index = -1;function compose() {  return dispatch(0)}function dispatch (i) {   if (i <= index) return Promise.reject(new Error('next() called multiple times'))   index = i   var fn = middleware[i]   if (i === middleware.length) fn = next   if (!fn) return Promise.resolve('fn is undefined')   try {    return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));   } catch (err) {    return Promise.reject(err)   } }  function f1(context,next){  console.log('middleware 1');  next().then(data=>console.log(data));  console.log('middleware 1');  return 'middleware 1 return'; } function f2(context,next){  console.log('middleware 2');  next().then(data=>console.log(data));  console.log('middleware 2');  return 'middleware 2 return'; } function f3(context,next){  console.log('middleware 3');  next().then(data=>console.log(data));  console.log('middleware 3');  return 'middleware 3 return'; }var middleware=[ f1,f2,f3]var context={};var next=function(context,next){  console.log('middleware 4');  next().then(data=>console.log(data));  console.log('middleware 4');  return 'middleware 4 return';};compose().then(data=>console.log(data));

直接运行结果如下:

"middleware 1"

"middleware 2"

"middleware 3"

"middleware 4"

"middleware 4"

"middleware 3"

"middleware 2"

"middleware 1"

"fn is undefined"

"middleware 4 return"

"middleware 3 return"

"middleware 2 return"

"middleware 1 return"

按着代码运行流程一步步分析:

dispatch(0)

i==0,index==-1 i>index 往下

index=0fn=f1Promise.resolve(f1(context, dispatch.bind(null, 0 + 1)))

这就会执行

f1(context, dispatch.bind(null, 0 + 1))            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选