当前位置: 首页 > 文档资料 > 阅读 express 源码 >

三、实验总结

优质
小牛编辑
129浏览
2023-12-01

你可能还是比较好奇 express 是怎么跑起来的?next 到底是什么东西,http.createServer 里面并没有 next 这个东西啊!

在以前,我有录制过一份关于 Koa 源码阅读的视频,记得是第五小节哦,点击这里了解洋葱圈模型 。除此之外,我们再次回顾一下,其实 next 函数在里面,只是被我们忽略掉了而已。

       ┌────────────────────────┐
       │   createApplication    │
       └────────────────────────┘
                    │
                    ▼
       ┌────────────────────────┐
       │       app.handle       │
       └────────────────────────┘
                    │
                    ▼
    ┌───────────────────────────────┐     ┌────────────────────────────────────┐
    │  router.handle(req,res,done)  │ ◀───│ done = finalHandle(req, res, opts) │                                            Λ
    └───────────────────────────────┘     └────────────────────────────────────┘                                           ╱ ╲
                    │                                                                                                     ╱   ╲
                    ▼                                                                  match router.stacks layer         ╱     ╲
       ┌────────────────────────┐          ┌───────────────────────────────────┐                                        ╱       ╲
       │         next()         │ ────────▶│              while()              │─────────────────────────────────────▶ ▕  layer  ▏
       └────────────────────────┘          └───────────────────────────────────┘                                        ╲       ╱
                    ▲                                                                                                    ╲     ╱
                    │                                                                                                     ╲   ╱
                    │                                                                                                      ╲ ╱
                    │                                                                                                       V
                    │                                                                                                       │
                    │                                                                                                       │
                    │                                                                                                       │
                    │                                                                                                       │
                    │                                                                                                       │
                    │                                                                                                       ▼
                    │                                                                       ┌────────────────────────────────────────────┐
                    │                                                                       │   layer.handle_request(req, res , next)    │
                    │                                                                       └─────────────────────────────────────┬──────┘
                    │                                                                                                             │
                    │                                                                                                             │
                    │                                                                                                             │
                    │           if on your function call next function ,they will be back next and enter next while loop.         │
                    │                                                                                                             │
                    └─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

因为不支持中文,所以就用了英文,意思就是假如在你自定义的函数里面调用 next 方法,这个 next 方法其实就是 router.handle 里面的方法 next,这里是把 next 当做引用传递了进去,当我们每次调用 next 就又回到 router.handle 里面的 next 方法,这样就形成了递归。

我们自己来写一段简化的代码,具体看你希望如何运行 arr 里面的 fn,我这里直接用的循环,即有平行也有串联,如下:

const testFunc = (str) => {
  return (next) => {
    if (str == 2) {
      console.log("2 号要加任务量哦~");

      console.log("==============");

      next([testFunc(3), testFunc(4), testFunc(5)])

      console.log("==============");

      return ;
    }
    console.log(str);
    next(); // 传递空的时候代表不需要在运行了
  }
};



function run (arr){

  if (!arr) {
    console.log("已经运行完啦!")
    return; // 递归的出口
  }

  arr.forEach(fn => {
    fn(run)
  });
}


run([testFunc(1), testFunc(2), testFunc(3)])

express 里面有一段匹配 layer 的 while 我给省略掉了,req 与 res 也省略掉了。留一个回调 next 作为接口,当每一次调用 next 又可以回到 run 方法。(这让我想起了一句话,在用递归函数之前,一定要考虑好出口),假如实在是难理解,就去看视频吧。觉得 => 箭头函数看起来费劲可以自己改成 function 的形式。