koa中间件的实现原理
koa中间件的实现原理如何?先来看一个例子。
koa的执行顺序是这样的:
const middleware = async function (ctx, next) {
console.log(1)
await next()
console.log(6)
}
const middleware2 = async function (ctx, next) {
console.log(2)
await next()
console.log(5)
}
const middleware3 = async function (ctx, next) {
console.log(3)
await next()
console.log(4)
}
会依次打印1,2,3,4,5,6
问题是koa中间件实现原理,也就是洋葱模型的实现原理是什么?
一、问题分析
async await是promise的语法糖,await后面跟一个promise,所以上面的代码可以写成:
const middleware = function (ctx, next) {
console.log(1)
next().then(() => {
console.log(6)
})
}
const middleware2 = function (ctx, next) {
console.log(2)
next().then(() => {
console.log(5)
})
}
const middleware3 = function (ctx, next) {
console.log(3)
next().then(() => {
console.log(4)
})
}
改成这样更好理解一些,所以流程控制的核心在于next的实现。
next要求调用队列中下一个middleware,当达到最后一个的时候resolve。这样最后面的promise先resolve,一直到第一个,这样就是洋葱模型的顺序了。
二、实现
koa-compose的实现是这样的:
function compose(middleware) {
return function (context, next) {
let index = -1
return dispatch(0)
function dispatch(i) {
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)
}
}
}
}
我们把一些参数检查的非核心逻辑去掉了,实现代码就上面那些。每次传入的next都是调用下一个middleware,这样是一个递归的过程,结束条件是最后一个middleware的next是用户传入的。
这里面有一些亮点:
- 这是一种尾递归的形式,尾递归的特点是最后返回的值是一个递归的函数调用,这样执行完就会在调用栈中销毁,不会占据调用栈.
- 返回的是一个Promise.resolve包装之后的调用,而不是同步的调用,所以这是一个异步递归,异步递归比同步递归的好处是可以被打断,如果中间有一些优先级更高的微任务,那么可以先执行别的微任务
- compose是函数复合,把n个middleware复合成一个,参数依然是context和next,这种复合之后依然是一个middleware,还可以继续进行复合。
三、总结
Koa 中间件的实现原理,也就是洋葱模型的实现原理,核心在于next的实现。next需要依次调用下一个middleware,当到最后一个的时候结束,这样后面middleware的promise先resolve,然后直到第一个,这样的流程也就是洋葱模型的流程了。
实现的时候还有一些细节,一个是递归最好做成尾递归的形式,而是用异步递归而不是同步递归,第三就是形式上用函数复合的形式,这样复合之后的中间件还可以继续复合。
koa中间件的实现原理的更多相关文章
- koa中间件系统原理及koa+orm2实践。
koa是由 Express 原班人马打造的新的web框架.套用其官方的说法:Koa 应用是一个包含一系列中间件 generator 函数的对象. 这些中间件函数基于 request 请求以一个类似于栈 ...
- 【nodejs原理&源码赏析(2)】KOA中间件的基本运作原理
[摘要] KOA中间件的基本运作原理 示例代码托管在:http://www.github.com/dashnowords/blogs 在中间件系统的实现上,KOA中间件通过async/await来在不 ...
- Koa中间件(middleware)级联原理
前言 上次看到了koa-compose的代码,今天来说一下koa中间件的级联以及工作原理. 中间件工作原理 初始化koa实例后,我们会用use方法来加载中间件(middleware),会有一个数组来存 ...
- KOA中间件的基本运作原理
示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 在中 ...
- koa 中间件
什么是 Koa 的中间件 通俗的讲:中间件就是匹配路由之前或者匹配路由完成做的一系列的操作,我们就可以 把它叫做中间件. 在express中间件(Middleware)是一个函数,它可以访问请求对象( ...
- Koa - 中间件(理解中间件、实现一个验证token中间件)
前言 Koa 应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的. 当一个中间件调用 next() 则该函数暂停并将控制传递给定义的下一个中间件.当在下游没有更多的中间件执行后 ...
- Koa 中间件的执行
Node.js 中请求的处理 讨论 Koa 中间件前,先看原生 Node.js 中是如何创建 server 和处理请求的. node_server.js const http = require(&q ...
- laravel中间件的实现原理
中间件的实现原理 运用 array_reduce 以及 call_user_func 实现 interface Middleware { public static function handle(C ...
- koa 基础(八)koa 中间件的执行顺序
1.koa 中间件的执行顺序 app.js /** * koa 中间件的执行顺序 */ // 引入模块 const Koa = require('koa'); const router = requi ...
- Koa 中间件的执行顺序
中间件工作原理 初始化koa实例后,我们会用use方法来加载中间件(middleware),会有一个数组来存储中间件,use调用顺序会决定中间件的执行顺序. 每个中间件都是一个函数(不是函数将报错), ...
随机推荐
- Notepad++轻量级java环境
2020-07-11 summary: Notepad++搭建轻量级java环境 notepad++搭建轻量级Java 原因:不想用eclipse 一.本机环境 Windows10 64位 已安装No ...
- python 创建虚拟环境python –m venv方式
1.环境准备 1.1.刷新包清单 sudo yum update 1.2.安装SCL实用程序 sudo yum install centos-release-scl 1.3.安装Python 3.6 ...
- WebApi 下载三维zip文件并预览
// 异步加载 const LoadObj = async (key?: string) => { LoadState.value = true var objStr, mtlStr var i ...
- jmeter性能测试学习1_配置oracl jdbc连接
1.导入orcle驱动的jar包 2.添加配置元件选择 JDBC连接配置 3.添加取样器 JDBCrequest 4.添加观察树,运行 配好密码 OK
- 学习Java的第一个代码
HelloWorld 新建一个文件夹 新建一个Java 文件后缀为java hello.java 编写代码 public class hello{ public static void main(St ...
- tail 命令 没有内容输出,记录一种解决
1. 没有内容输出的命令: tail - f /test/platform/jtimer.log 控制台: 2. 当切换到此文件的当前路径后才有: 使用: tail - f jtimer.log
- springMVC的定时器
大家好,本人从事软件行业已有8年,大部分时间从事软件开发编写工作.好了废话少说了哈哈哈,直接干货. 在Java开发过程中有很多业务需求里面需要我们实时处理一些动态的业务比如库存的数据动态更新,实时数据 ...
- ESP32 环境搭建以及入门编程流程和体验-windows
本帖适合入门级人员,但同时欢迎新老读者批评指正. 某宝上买了个esp32,还有一本ESP32开发指南的书. 然后就是环境搭建.上面写的主要是linux上的,我在自己的orange pi pc开发板上搭 ...
- PRVF-4007 : User equivalence check failed for user "grid"
PRVF-4007 : User equivalence check failed for user "grid" 问题:Oracle安装Grid Infrastructure之前 ...
- cadence-ADE反相器仿真
Cadence-ADE仿真 连接电路 鼠标移至schematic绘制区域,单击放置inv i键继续添加gnd, vdc(3.3V), vpulse(0-3.3V,Period 1us,Pulse wi ...