深入浅析Nodejs中的“洋葱模型”

老丽大大_6836

老丽大大_6836

2021-05-07

4727人浏览

转载

本篇文章带大家了解一下nodejs中的“洋葱模型”。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

目前比较流行的 Node.js 框架有Express、KOA和Egg.js,其次是另外一个正在兴起的与 TypeScript 相关的框架——Nest.js,无论是哪个 Node.js 框架,都是基于中间件来实现的,而中间件(可以理解为一个类或者函数模块)的执行方式就需要依据洋葱模型

推荐学习:《nodejs 教程》

1. 洋葱模型

洋葱我们都知道,一层包裹着一层,层层递进,但是现在不是看其立体的结构,而是需要将洋葱切开来,从切开的平面来看,如图 所示:

1.png

可以看到要从洋葱中心点穿过去,就必须先一层层向内穿入洋葱表皮进入中心点,然后再从中心点一层层向外穿出表皮,这里有个特点:进入时穿入了多少层表皮,出去时就必须穿出多少层表皮。先穿入表皮,后穿出表皮,符合我们所说的栈列表,先进后出的原则。

2. 洋葱模型与Node的关系

目前比较流行的 Node.js 框架有Express、KOA 和 Egg.js,无论是哪个 Node.js 框架,都是基于中间件来实现的,而中间件(可以理解为一个类或者函数模块)的执行方式就需要依据洋葱模型

洋葱的表皮我们可以思考为中间件:

从外向内的过程是一个关键词 next();而从内向外则是每个中间件执行完毕后,进入原来的上一层中间件,一直到最外一层。

3. 中间件的执行

以express为例,以下就是中间件的一个基本执行过程:

2.png、3.png

Koa是基于Express的同一班人马开发的下一代node框架,二者的主要区别:

  • Express 封装、内置了很多中间件,比如 connect 和 router ,而 KOA 则比较轻量,开发者可以根据自身需求定制框架;
  • Express 是基于 callback 来处理中间件的,而 KOA 则是基于 await/async;
  • 在异步执行中间件时,Express 并非严格按照洋葱模型执行中间件,而 KOA 则是严格遵循的(体现再两者在中间件为异步函数的时候处理会有不同)。

Express 和 KOA 之间关于洋葱模型的执行方式的区别介绍:

Nodejs Patterns
Nodejs Patterns

内容:生产级 Node.js 后端模式,涵盖 Express/Fastify 配置、分层架构、中间件、错误处理、验证、数据库集成、身份验证及缓存。 时机:构建 REST API、搭建 Node.js 服务器、实施身份验证、集成数据库、添加验证/缓存或构建后端应用结构时。 关键词:nodejs, node, express, fastify, typescript, api, rest, 中间件, 身份验证, jwt, 验证, zod, postgres, mongodb, redis, 缓存, 速率限

下载

我们保留上述示例代码的原来三个中间件,同时在 2 和 3 之间插入一个新的异步中间件,代码如下:

(1)express

/**
 * 异步中间件
 */
app.use(async (req, res, next) => {
    console.log('async');
    await next();
    await new Promise(
        (resolve) => 
            setTimeout(
                () => {
                    console.log(`wait 1000 ms end`);
                    resolve()
                }, 
            1000
        )
    );
    console.log('async end');
});

然后将其他中间件修改为 await next() 方式,如下中间件 1 的方式:

/**
 * 中间件 1
 */
app.use(async (req, res, next) => {
    console.log('first');
    await next();
    console.log('first end');
});

重新运行,最终输出结果为:

4.png

可以看出,从外向内的是正常的,一层层往里进行调用,从内向外时则发生了一些变化,最主要的原因是异步中间件并没有按照顺序输出执行结果。

(2)Koa保持上面的代码顺序,只将对应的express语法改成koa语法,其中中间件1和异步中间件代码部分如下示例:

const Koa = require('koa');
const app = new Koa();
/**
 * 中间件 1
 */
app.use(async (ctx, next) => {
    console.log('first');
    await next();
    console.log('first end');
});
/**
 * 异步中间件
 */
app.use(async (ctx, next) => {
    console.log('async');
    await next();
    await new Promise(
        (resolve) => 
            setTimeout(
                () => {
                    console.log(`wait 1000 ms end`);
                    resolve()
                }, 
            1000
        )
    );
    console.log('async end');
});

重新运行,最终输出结果为:

5.png

你会发现,KOA 严格按照了洋葱模型的执行,从上到下,也就是从洋葱的内部向外部,输出 first、second、async、third;接下来从内向外输出 third end、async end、second end、first end。

更多编程相关知识,请访问:编程教学!!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

nodejs

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

2026.02.13

312

17

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

2026.02.25

540

17

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

2026.03.13

391

19

TypeScript 全栈开发进阶指南
TypeScript 全栈开发进阶指南

面向有 JavaScript 基础的开发者,深入讲解 TypeScript 的类型系统与全栈开发实践。

2026.06.03

306

29

TypeScript Node.js 全栈工程化与Monorepo架构实践
TypeScript Node.js 全栈工程化与Monorepo架构实践

本专题围绕 TypeScript 在 Node.js 全栈开发中的工程化实践展开,系统讲解 Monorepo 架构设计、包管理策略、模块复用机制以及服务端与前端统一类型系统的构建方法。通过真实项目案例,帮助开发者提升大型全栈项目的可维护性与协作效率。

2026.06.16

698

8

node.js调试
node.js调试

node.js调试可以使用console.log()输出调试信息、断点调试和第三方调试工具。详细介绍:1、console.log()输出调试信息,通过在代码中插入console.log()语句,开发人员可以在控制台输出变量的值、函数的执行结果等信息,以便观察代码的执行流程和状态;2、断点调试,可以在代码中设置断点,以便在特定位置暂停代码的执行,观察变量的值和执行流程等。

2023.09.19

11809

8

JavaScript 全栈开发基础(Node.js + 前端)
JavaScript 全栈开发基础(Node.js + 前端)

本专题系统介绍 JavaScript 在全栈开发中的核心知识结构,涵盖 Node.js 基础、Express/Koa 接口构建、前端交互设计、模块化与包管理、数据库连接、前后端数据通信与部署流程。通过完整项目示例,帮助学习者掌握从浏览器到服务器的一体化开发能力,实现真正意义上的全栈入门。

2025.11.26

454

14

Node.js后端开发与Express框架实践
Node.js后端开发与Express框架实践

本专题针对初中级 Node.js 开发者,系统讲解如何使用 Express 框架搭建高性能后端服务。内容包括路由设计、中间件开发、数据库集成、API 安全与异常处理,以及 RESTful API 的设计与优化。通过实际项目演示,帮助开发者快速掌握 Node.js 后端开发流程。

2026.02.10

781

17

JavaScript Node.js流处理与高效数据管道构建实践
JavaScript Node.js流处理与高效数据管道构建实践

本专题聚焦 Node.js 在大规模数据处理场景中的应用,系统讲解 Stream 流机制、背压控制、管道(Pipe)处理以及文件与网络数据流的高效传输方式。内容包括可读流、可写流、双工流与转换流的实现原理,并结合实际案例构建高性能数据处理管道,帮助开发者提升数据处理效率与系统吞吐能力。

2026.04.07

344

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
快速入门Node.JS全套完整版
快速入门Node.JS全套完整版

共83课时 | 13.6万人学习

nodejs开发基础教程
nodejs开发基础教程

共15课时 | 4.9万人学习

JavaScript设计模式视频教程
JavaScript设计模式视频教程

共28课时 | 6.3万人学习