zoukankan      html  css  js  c++  java
  • Koa中间件(middleware)级联原理

    前言

    • 上次看到了koa-compose的代码,今天来说一下koa中间件的级联以及工作原理。

    中间件工作原理

    • 初始化koa实例后,我们会用use方法来加载中间件(middleware),会有一个数组来存储中间件,use调用顺序会决定中间件的执行顺序。
    • 每个中间件都是一个函数(不是函数将报错),接收两个参数,第一个是ctx上下文对象,另一个是next函数(由koa-compose定义)
    • 在建立好http服务器后,会调用koa-compose模块对middleware中间件数组进行处理。具体代码这里就不贴了,原理就是:会从middleware数组中取第一个函数开始执行,中间件函数中调用next方法就会去取下一个中间件函数继续执行。每个中间件函数执行完毕后都会返回一个promise对象。(ps:调用next方法并不是表示当前中间件函数执行完毕了,调用next之后仍可以继续执行其他代码)

    示例代码

     1 const Koa = require('koa')
     2 const app = new Koa()
     3 app.use((ctx, next) => {
     4     console.log(1)
     5     next()
     6     console.log(3)
     7 })
     8 app.use((ctx) => {
     9     console.log(2)
    10 })
    11 app.listen(3001)
    • 上述示例代码仅是用于,在命令行观察中间件执行顺序。执行结果自然是1 -> 2 -> 3。两个函数看做是两个中间件,第一个函数调用next时就会执行第二个中间件函数。
    • 中间件函数队列,会在最后一个中间件或一个没有调用next的中间件那里停止。就比如第一个中间件没有调用next,那么后续的中间件函数都不会执行。
    • 但如果第二个函数中存在异步,比如setTimeout(() => {console.log(2)}, 2000),那结果就变成1 -> 3 -> 2了。如果要保证第二个中间件函数执行完毕后, 才执行第一个中间件函数next之后的代码的话,就需要使用async/await了。

    示例代码2

    • 接下来我们要保证中间件2里异步代码执行完毕后,才去执行中间件1next函数之后的代码。
    • 具体做法是,第一个中间件使用async/await,第二个中间件返回一个promise对象,执行完毕异步代码后再resolve,调用next()得到的就是第二个中间件返回的数据。
     1 const Koa = require('koa')
     2 const app = new Koa()
     3 app.use(async (ctx, next) => {
     4     console.log(1)
     5     await next() // 这里得到的就是中间件2返回的promise对象
     6     console.log(3)
     7 })
     8 app.use((ctx) => {
     9     return new Promise((resolve,reject) => {
    10         setTimeout(() => {
    11             console.log(2)
    12             resolve()
    13         }, 2000)
    14     })
    15 })
    16 app.listen(3001)
    • 这样就保证了代码的执行顺序

    中间件执行顺序

     
    • 上面是在网上找的一个示意图,就是说中间件执行就像洋葱一样,最早use的中间件,就放在最外层。处理顺序从左到右,左边接收一个request,右边输出返回response。
    • koa官方文档上把外层的中间件称为"上游",内层的中间件为"下游"。
    • 一般的中间件都会执行两次,调用next之前为第一次,调用next时把控制传递给下游的下一个中间件。当下游不再有中间件或者没有执行next函数时,就将依次恢复上游中间件的行为,让上游中间件执行next之后的代码

    参考博客:https://www.jianshu.com/p/02ed208d4577

    今天你学习了吗!!!
  • 相关阅读:
    莫比乌斯反演学习笔记
    NOIp 2020 游记
    题解【LOJ3087】「GXOI / GZOI2019」旅行者
    题解【CF999E】Reachability from the Capital
    题解【LOJ2007】「SCOI2015」国旗计划
    题解【LOJ3145】「APIO2019」桥梁
    题解【LOJ2114】「HNOI2015」菜肴制作
    CSP-J/S 2020 爆炸记
    题解【洛谷P2569】[SCOI2010]股票交易
    补题目录
  • 原文地址:https://www.cnblogs.com/nayek/p/11703572.html
Copyright © 2011-2022 走看看