前言

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

中间件工作原理

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

示例代码

 const Koa = require('koa')
const app = new Koa()
app.use((ctx, next) => {
console.log(1)
next()
console.log(3)
})
app.use((ctx) => {
console.log(2)
})
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()得到的就是第二个中间件返回的数据。
 const Koa = require('koa')
const app = new Koa()
app.use(async (ctx, next) => {
console.log(1)
await next() // 这里得到的就是中间件2返回的promise对象
console.log(3)
})
app.use((ctx) => {
return new Promise((resolve,reject) => {
setTimeout(() => {
console.log(2)
resolve()
}, 2000)
})
})
app.listen(3001)
  • 这样就保证了代码的执行顺序

中间件执行顺序

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

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

Koa中间件(middleware)级联原理的更多相关文章

  1. 【nodejs原理&源码赏析(2)】KOA中间件的基本运作原理

    [摘要] KOA中间件的基本运作原理 示例代码托管在:http://www.github.com/dashnowords/blogs 在中间件系统的实现上,KOA中间件通过async/await来在不 ...

  2. koa中间件系统原理及koa+orm2实践。

    koa是由 Express 原班人马打造的新的web框架.套用其官方的说法:Koa 应用是一个包含一系列中间件 generator 函数的对象. 这些中间件函数基于 request 请求以一个类似于栈 ...

  3. KOA中间件的基本运作原理

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 在中 ...

  4. Koa 中间件的执行顺序

    中间件工作原理 初始化koa实例后,我们会用use方法来加载中间件(middleware),会有一个数组来存储中间件,use调用顺序会决定中间件的执行顺序. 每个中间件都是一个函数(不是函数将报错), ...

  5. koa 中间件

    什么是 Koa 的中间件 通俗的讲:中间件就是匹配路由之前或者匹配路由完成做的一系列的操作,我们就可以 把它叫做中间件. 在express中间件(Middleware)是一个函数,它可以访问请求对象( ...

  6. Koa 中间件的执行

    Node.js 中请求的处理 讨论 Koa 中间件前,先看原生 Node.js 中是如何创建 server 和处理请求的. node_server.js const http = require(&q ...

  7. laravel框架的中间件middleware的详解

    本篇文章给大家带来的内容是关于laravel框架的中间件middleware的详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. laravel中间件是个非常方便的东西,能将一些逻辑 ...

  8. laravel中间件的实现原理

    中间件的实现原理 运用 array_reduce 以及 call_user_func 实现 interface Middleware { public static function handle(C ...

  9. Django框架之中间件MiddleWare

    Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出.中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健 ...

随机推荐

  1. Serlvet之cookie和session学习

    HTTP 协议 Web通信需要一种语言,就像中国人讲中文,欧美说英文,Web使用的HTTP协议,也叫超文本协议. 使用HTTP协议的人分为两类:客户端和服务端.请求资源的角色是客户端,提供资源的是服务 ...

  2. Python3.7.1学习(一):redis的连接和简单使用

    1.python 利用 redis 第三方库 首先安装:pip install redis 2.reids的连接 Redis使用StrictRedis对象来管理对一个redis server 的所有连 ...

  3. 领扣(LeetCode)七进制数 个人题解

    给定一个整数,将其转化为7进制,并以字符串形式输出. 示例 1: 输入: 100 输出: "202" 示例 2: 输入: -7 输出: "-10" 注意: 输入 ...

  4. 函数式接口的使用 (Function、Predicate、Supplier、Consumer)

    参考:https://blog.csdn.net/jmj18756235518/article/details/81490966 函数式接口 定义:有且只有一个抽象方法的接口 Function< ...

  5. ubuntu 16.04源码编译OpenCV教程 | compile opencv on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/15f5c3e8/,欢迎阅读! compile opencv on ubuntu 16.04 Series Part 1: comp ...

  6. 线程池ThreadPoolExecutor的使用方法

    方法我们通过继承Thread类和实现runnable接口或者callable接口三种方式实现. 继承Thread类实际上也是实现了runnable接口,被继承的类主要是实现run()方法,通过star ...

  7. Stream系列(七)distinct方法使用

    EmployeeTestCase.java package com.example.demo; import lombok.Data; import lombok.ToString; import l ...

  8. Spring项目中优雅的异常处理

    前言 如今的Java Web项目多是以 MVC 模式构建的,通常我们都是将 Service 层的异常统一的抛出,包括自定义异常和一些意外出现的异常,以便进行事务回滚,而 Service 的调用者 Co ...

  9. 【记录】洛谷P1739-表达式括号匹配AC记

    题面请查看:https://www.luogu.org/problem/P1739 思路: 见到括号就搜索,搜到与它配对的括号为止,搜不到就输出NO 代码: #include <bits/std ...

  10. JAVA,Python代码是编译执行还是解释执行?

    转载地址:http://blog.csdn.net/zv3e189os5c0tsknrbcl/article/details/78661641 有人在讨论 Python 代码是编译执行还是解释执行?这 ...