Koa2 洋葱模型 —— compose 串联中间件的四种实现

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

在这里插入图片描述


阅读原文


前言

Koa 是当下主流 NodeJS 框架,以轻量见长,而它中间件机制与相对传统的 Express 支持了异步,所以编码时经常使用 async/await,提高了可读性,使代码变得更优雅,上一篇文章 NodeJS 进阶 —— Koa 源码分析,也对 “洋葱模型” 和实现它的 compose 进行分析,由于个人觉得 compose 的编程思想比较重要,应用广泛,所以本篇借着 “洋葱模型” 的话题,打算用四种方式来实现 compose


洋葱模型案例

如果你已经使用 Koa 对 “洋葱模型” 这个词一定不陌生,它就是 Koa 中间件的一种串行机制,并且是支持异步的,下面是一个表达 “洋葱模型” 的经典案例。

const Koa = require("koa");

const app = new Koa();

app.use(asycn (ctx, next) => {
   
   
    console.log(1);
    await next();
    console.log(2);
});

app.use(asycn (ctx, next) => {
   
   
    console.log(3);
    await next();
    console.log(4);
});

app.use(asycn (ctx, next) => {
   
   
    console.log(5);
    await next();
    console.log(6);
});

app.listen(3000);

// 1
// 3
// 5
// 6
// 4
// 2

上面的写法我们按照官方推荐,使用了 async/await,但如果是同步代码不使用也没有关系,这里简单的分析一下执行机制,第一个中间件函数中如果执行了 next,则下一个中间件会被执行,依次类推,就有了我们上面的结果,而在 Koa 源码中,这一功能是靠一个 compose 方法实现的,我们本文四种实现 compose 的方式中实现同步和异步,并附带对应的案例来验证。


准备工作

在真正创建 compose 方法之前应该先做些准备工作,比如创建一个 app 对象来顶替 Koa 创建出的实例对象,并添加 use 方法和管理中间件的数组 middlewares

// 文件:app.js
// 模拟 Koa 创建的实例
const app = {
   
   
    middlewares: []
};

// 创建 use 方法
app.use = function(fn) {
   
   
    app.middlewares.push(fn);
};

// app.compose.....

module.exports = app;

上面的模块中导出了 app 对象,并创建了存储中间件函数的 middlewares 和添加中间件的 use 方法,因为无论用哪种方式实现 compose 这些都是需要的,只是 compose 逻辑的不同,所以后面的代码块中会只写 compose 方法。


Koa 中 compose 的实现方式

首先介绍的是 Koa 源码中的实现方式,在 Koa 源码中其实是通过 koa-compose 中间件来实现的,我们在这里将这个模块的核心逻辑抽取出来,用我们自己的方式实现,由于重点在于分析 compose 的原理,所以 ctx 参数就被去掉了,因为我们不会使用它,重点是 next 参数。

1、同步的实现

// 文件:app.js
app.compose = function() {
   
   
    // 递归函数
    function dispatch(index) {
   
   
        // 如果所有中间件都执行完跳出
        if (index === app.
koa - 洋葱模型浅析 ,它的核心工作包括下面两个方面:如下图: 如下是洋葱代码的案例: 4.源码解析 use方法 listen方法 compose方法 compose方法是洋葱模型的核心,compose方法中有一个dispatch方法,第一次调用的时候,执行的是第一个中间件函数,中间件函数执行的时候就是再次调用dispatch函数,也就说形成了一个递归,这就是next函数执行的时候会执行下一个中间件的原因,因此形成了一个洋葱模型。 5.为什么需要洋葱模型? 因为很多时候,在一个app里面有很多中间件,,用葱模型 阅读详情

相关推荐

compose-middleware:将一组中间件组成一个函数,以用于Express,Connect,路由器等

撰写中间件 将一系列中间件组成一个函数,以用于Express,Connect,路由器等。 安装 npm install compose-middleware --save 用法 将多个中间件功能组合到单个请求中间件处理程序中,并支持内联错误处理中间件。 var express = require ( "express" ) ; var compose = require ( "compose-middleware" ) . compose ; var app = express ( ) ; app . use ( compose ( [ function ( req , res

koa2源码剖析和koa-compose实现

简介 Koa由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数。同时koa中间件机制和洋葱模型是它独有的特点,并且它没有捆绑任何中间件,而是可以让用户以更优雅的方式去扩展。 Koa是一个精简的web框架,它主要做了以下几件事: 为request和response对象赋能,并基于它们封装成一个context对象,可以通过get,set调用参数 基于async/await

越努力越幸运 2499

KOA2 compose 串联中间件实现洋葱模型

前言Koa 是当下主流 NodeJS 框架,以轻量见长,而它中间件机制与相对传统的 Express 支持了异步,所以编码时经常使用 async/await,提高了可读性,使代码变得更优雅,上一篇文章 NodeJS 进阶 —— Koa 源码分析,也对 “洋葱模型” 和实现它的 compose 进行分析,由于个人觉得 compose 的编程思想比较重要,应用广泛,所以本篇借着 “洋葱模型” 的话题,打...

weixin_34018202的博客 424

koa工作原理:实现compose函数来实现AOP

NodeNote,持续更新中react相关库源码浅析, react ts3 项目 [TOC] koa类的结构 module.exports = class Application extends Emitter{ constructor() { super(); this.proxy = false; this.middleware = []; this....

weixin_34318272的博客 584

KOA2 compose 串联中间件实现洋葱模型

Koa 是当下主流 NodeJS 框架,以轻量见长,而它中间件机制与相对传统的 Express 支持了异步,所以编码时经常使用 async/await ,提高了可读性,使代码变得更优雅,上一篇文章 NodeJS 进阶 —— Koa 源码分析 ,也对 “洋葱模型” 和实现它的 compose 进行分析,由于个人觉得 compose 的编程思想比较重要,应用广泛,所以本篇借着 “洋葱模型” 的话题,打...

li420520的博客 1191

Koa2洋葱模型是什么?它是如何实现的?

在下一个中间件函数执行完毕后,控制权会再次回到当前中间件函数,执行剩余的代码。关键字的配合,实现中间件函数的顺序执行和控制权的传递。Koa2洋葱模型是一种中间件执行流程的设计模式,它允许开发者在请求的处理过程中,按照特定的顺序依次执行一系列中间件函数。然后,我们定义一些中间件函数,这些函数将按照洋葱模型的顺序依次执行。可以看到,中间件函数的执行顺序是从外到内,然后再从内到外。总结一下,Koa2洋葱模型是一种中间件执行流程的设计模式,通过。在每个中间件函数中,我们首先输出一个开始的日志,然后调用。

jakelihua 531

解密Koa.js洋葱模型中间件执行流程的核心原理

Koa.js作为一款轻量级的Node.js Web框架,其独特的**洋葱模型**中间件机制是实现高效请求处理的核心。这种设计模式允许开发者通过层层嵌套的中间件对HTTP请求进行精细化的拦截、处理和响应,极大提升了代码的可扩展性和复用性。本文将深入解析洋葱模型的工作原理,帮助新手开发者快速掌握这一核心概念。 ## 一、洋葱模型的核心概念:什么是中间件? 在Koa.js中,**中间件**是一个接收

gitblog_01086的博客 712

仿koa2 compose实现自己的中间件

仿koa2 compose实现自己的中间件 临时接到任务,要写中间件,然后就仿照了两篇博客进行了改动,这两篇博客会在最后给出。 app.js class App { constructor() { this.middlewares = []; } use(fn) { if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!'); this.mi

qq_32862143的博客 218

学习 koa 源码的整体架构,浅析koa洋葱模型原理和co原理

面试题千万不要死记,一定要自己理解,用自己的方式表达出来,在这里预祝各位成功拿下自己心仪的offer。需要完整面试题的朋友可以点击蓝色字体获取f (!/***/自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

2301_76379381的博客 767

【源码学习----koakoa中间件核心(koa-compose)源码解读分析(洋葱模型解析)

最近经常使用koa进行服务端开发,迷恋上了koa洋葱模型,觉得这玩意太好用了。而且koa是以精简为主,没有很多集成东西,所有的东西都需按需加载,这个更是太合我胃口了哈哈哈哈。 相对与express的中间件,express的中间件使用的是串联,就像冰糖葫芦一样一个接着一个,而koa使用的V型结构(洋葱模型),这将给我们的中间件提供更加灵活的处理方式。 基于对洋葱模型的热衷,所以对koa洋葱模型进行一探究竟,不管是koa1还是koa2中间件都是基于koa-compose进行编写的,这种V型结构的实现就来源

零信号的博客 385

浅析Node中间件Koa&Express:原理和实现

说到中间件,很多开发者都会想到 Koa.js,其中间件设计无疑是前端中间件思想的典型代表之一。 最近重新温习这部分内容,按奈不住想要和各位看官聊聊其中绝妙! Koa用起来非常方便——比之express,它“完美中间件”的设计让功能之间看起来非常简洁!笔者在项目中就曾这样使用过: const Koa=require('koa') const app=new Koa() const Router=require('koa-router') const router=new Router() const cor

flying meng的菜鸟居 7181

手写一个 Koa中间件洋葱模型与异步执行原理

composeKoa 的灵魂递归 + Promise 串联,next就是"进入下一层"的引用洋葱 = 进入时 1→2→3,await返回后 3→2→1 的后置执行ctx 用原型 getter/setter 做"活委托",body 只标记、响应统一在最后输出全局错误 = 中间件链 Promise 的 catch,emit 给整个核心不到 150 行——读完源码你就不会再怕框架了。

小二丶的博客 199

【源码】koa-compose洋葱模型原理解析---函数多层调用怎么写更优雅?

资料准备 【若川】koa 洋葱模型实现:https://juejin.cn/post/7005375860509245471 【函数式编程指北】:https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/ch5.html https://www.yuque.com/docs/share/0268760e-60bf-4278-871e-c1e83a68be7a # 克隆git clone https://github.com

rbgg_mp的博客 453

Koa中间件(middleware)实现探索

说起Node,最常用的估计就是express和koa,两者都用到了中间件(middleware)这一概念,主要用于对请求的统一处理。koa的请求处理是典型的洋葱模型,下面是官方的配图,而这一模型的组成部分就是middleware 接下来我们来看一下koa的源码,了解中间件实现方式。

u012362458的博客 1100
上一篇: NodeJS 进阶 —— Koa 源码分析
Panda Shen
博客等级 码龄9年 18粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值