使用异步编程保证Koa的洋葱模型

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

👨‍💻 博客主页:作者主页
👍 觉得文章不错的朋友可以点点赞和关注
🎁 粉丝福利:学习资料、简历模板统统都有点击领取

koa框架的业务流程是一个完全的异步编程模型,通过ctx上下文对象来贯穿http的上下游。对我们来说最重要的就是理解洋葱模型。

先来看一个经典的洋葱图认识一下

我们先来看一下这个代码

const Koa = require('koa')
const app = new Koa()
//第一个中间件
app.use((ctx, next) => {
    console.log("第一个中间件", 1);
    next()
    console.log("第一个中间件", 2);
})
//第二个中间件
app.use((ctx, next) => {
    console.log("第二个中间件", 3);
    next()
    console.log("第二个中间件", 4);
})
//第三个中间件
app.use((ctx, next) => {
    console.log("第三个中间件", 5);
    console.log("第三个中间件", 6);
})
app.listen(3000, () => {
    console.log("Koa已经开启在http://loclhost:3000");
})

我们运行这个代码在浏览器打开并返回控制台看一下打印

第一个中间件 1
第二个中间件 3
第三个中间件 5
第三个中间件 6
第二个中间件 4
第一个中间件 2

大家可以看这段代码,其执行效果为135642,也就是说这就好比第一个中间件把第二个包裹了起来,第三个中间件又把第二个中间件包起来了,调用next时就回去执行第二个中间件,结束后继续执行第一个。

所以他的顺序应该是这样的

看到上图相信大家已经非常的了解了吧。

然后下面我们会用到async await这个语法糖,我在这里简单介绍一下async函数

它是generator函数的语法糖,可以通过 yield(中文翻译动词为提供,暂时叫他提供) 关键字,就是把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。

async函数,就是将generator函数的*换成async,将yield替换成await

简单来说async/await,就是异步编程回调函数写法的替代方法,暂且就说这么多,下一篇文章我再详细介绍async await函数,

再多说一句 async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。

我们再反观这个洋葱模型

然后我再在第三个中间件加了个axios请求,因为他是异步的操作,所以我得再在前面加个async,然后再在请求的前面加个await,这样我们就可以得到get请求的这个结果,如果不加,他返回的是一个Promise对象

这里是加了async await函数的,但是…

const Koa = require('koa')
const app = new Koa()
    //第一个中间件
app.use((ctx, next) => {
        console.log("第一个中间件", 1);
        next()
        console.log("第一个中间件", 2);
    })
    //第二个中间件
app.use((ctx, next) => {
        console.log("第二个中间件", 3);
        next()
        console.log("第二个中间件", 4);
    })
    //第三个中间件
app.use(async(ctx, next) => {
    console.log("第三个中间件", 5);
    const axios = require("axios")
    const res = await axios.get('http://www.baidu.com')
    console.log(res);
    console.log('发送了axios请求');
    console.log("第三个中间件", 6);
})
app.listen(3000, () => {
    console.log("Koa已经开启在http://localhost:3000");
})

我们自行打印这个结果,可以看到

中间省略…

可以看到,我们虽然取回了这个res结果,但是它的打印顺序变了,也就是它遇到await后就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。

但是这不符合我们想要的结果,我们想要的是它按照本来的顺序执行,

然后我们为了保证洋葱模型,我们应该如下改动,将前面的代码也添加async await用来控制情况在我们预期之内。

const Koa = require('koa')
const app = new Koa()
//第一个中间件
app.use(async(ctx, next) => {
    console.log("第一个中间件", 1);
    await next()
    console.log("第一个中间件", 2);
})
//第二个中间件
app.use(async(ctx, next) => {
    console.log("第二个中间件", 3);
    await next()
    console.log("第二个中间件", 4);
})
//第三个中间件
app.use(async(ctx, next) => {
    console.log("第三个中间件", 5);
    const axios = require("axios")
    const res = await axios.get('http://www.baidu.com')
    console.log('发送了axios请求');
    console.log("第三个中间件", 6);
})
app.listen(3000, () => {
    console.log("Koa已经开启在http://loclhost:3000");
})

运行代码我们可以看到

中间省略…

所以我们在写中间件函数的时候,一般都将中间件变成async await函数,这样就不会因为异步编程导致洋葱模型不可控以至于不合理

以上是我自己的理解,如果有更多的比如我说不清的,可以留言告诉我,我会好好去学习,大家一起把问题说出来互相学习,希望大家不要吝啬,求求各位大佬了

【项目准备】大模型对话机器人 (1)中间件是什么?异步函数,可以执行一些操作,用来处理http请求。有两个参数ctx和next,ctx用来获取请求信息、发送响应内容,next用来将控制权传递给下一个中间件函数。(2)为什么要有中间件?处理 Web 请求时,服务端常常需要进行验证请求来源、检查登录状态、确定是否有足够权限、打印日志等操作,而这些重复的操作如果写在具体的路由处理函数中,明显会导致代码冗余,这个时候,我们就可以将这些通用的流程抽象为中间件函数,减少重复代码。(3)具体跨域和鉴权中间件怎么实现的。 阅读详情

相关推荐

深入剖析Koa接口封装原理,洋葱模型?递归调用?

本文深入剖析Koa接口设计原理讲解一下koa在封装接口时使用洋葱模型以及洋葱模型实现原理递归调用本文深入剖析Koa接口设计原理,结合代码详细的讲解了洋葱模型的实现原理希望看到这里的你能够有所收获!!!

舜意的博客 1232

JAVA DDD架构之洋葱架构

从Spring 4.3开始,单个构造器的情况下会自动注入,不需要显式@Autowired。A: 使用领域事件+最终一致性,或者应用层的@Transactional。:对于生产环境,可以用Kafka或RabbitMQ替换简单的内存发布器。如果有多个构造器,需要在想要使用的构造器上添加@Autowired。人工干预:对于持久化的失败事件,可以提供管理界面进行人工处理。- 最内层,包含实体、值对象、聚合根、领域服务等。:构造器只做初始化,不包含业务逻辑。这是优点而非缺点,促使更好的设计。

weixin_45553053的博客 2339

深入理解 Koa 中间件之 “ 洋葱模型

欢迎关注我的公众号『 **前端我废了** 』,查看更多文章!!!

Cyj1414589221的博客 1089

深入理解洋葱模型

作者:掘金@苏里 https://juejin.im/post/6844904025767280648前言本文来由,希望可以剖析中间件的组合原理,从而帮助大家更加理解洋葱模型。话不多...

程序员成长指北 8306

Koa】初识 Koa

有时,某些中间件希望添加一些额外的信息,以方便后续中间件处理,比如当前登录的用户信息。Koa建议把这些信息添加到ctx.state中该属性默认是一个空对象,专门提供给中间件开发者添加额外信息的。

小秀的博客 1419

三言两语说透koa洋葱模型

Compose函数可以将需要顺序执行的多个函数复合起来,后一个函数将前一个函数的执行结果作为参数。这里利用了函数递归的机制。dispatch函数接收当前中间件的索引i,如果i大于中间件数组长度,则执行next函数。compose接收一个中间件数组作为参数,执行数组中的中间件,返回一个可以执行所有中间件的函数。所有中间件的回调函数中,执行中间件函数的时候,递归调用dispatch,同时将索引+1,表示执行下一个中间件。每个中间件都可以捕获自己的错误,并且不会影响其他中间件的执行,这样对错误处理更加友好。

qq_36789311的博客 1159

Koa中间件洋葱模型、async和await(前端面试)

koa中间件 先用new将koa实例化,实例化出来的koa对象称为应用程序对象,包含了很多的中间件 使用app.listen方法启动,listen里面包含了很多的参数,使用端口号将koa启动 小程序需要向服务器发送HTTP请求,koa也要接收HTTP请求,这时需要使用中间件 中间件也就是函数,定义一个中间件也就是定义一个函数,如何将一个函数变为中间件,需要使用app.use方法注册中间件 测试:浏览器向服务器发送HTTP请求,localhost:3000,此时服务器koa通过中间件接收请求,打印相应的结

S_snowxue的博客 687

Koa是什么

koa是下一代的 Node.js Web 框架,旨在提供更简洁、更高效的 Web 应用开发体验。

weixin_53541596的博客 840

从零打造高并发游戏后端:Koa框架终极实战指南

想要构建高性能的游戏服务器?Koa框架正是你需要的利器!作为Express.js原班人马打造的下一代Node.js Web框架,Koa凭借其优雅的中间件设计和强大的异步处理能力,成为游戏后端开发的首选方案。🎮 Koa是一个轻量级的HTTP中间件框架,采用ES6生成器和async/await语法,让异步编程变得异常简单。它的核心代码只有约570行,却提供了强大的功能和出色的性能表现。 ## ?

gitblog_01054的博客 1033

探秘 Koa2-Blog: 一个现代、高效的 Node.js 博客框架

探秘 Koa2-Blog: 一个现代、高效的 Node.js 博客框架 如果你是 Node.js 的开发者或者正在寻找一个简洁而强大的博客系统, 是一个值得你关注的开源项目。这个基于 Koa2 框架构建的博客平台,以其模块化设计和高度可定制性,为开发人员提供了一个优雅的解决方案。 项目简介 Koa2-Blog 是一个由 JavaScript 编写的轻量级博客应用,利用了最新的 Node.js 特性...

gitblog_00023的博客 351

koa源码阅读之koa-compose/application.js

koa源码阅读之koa-compose/application.js koa-Compose 为了理解方便特地把注释也粘进来 //这英语。我也来翻译一波 //大概就是把所有的中间件组合返回一个完整大块的中间件 /** * Compose `middleware` returning * a fully valid middleware...

weixin_34357436的博客 160

后端Node知识框架图(Node、Express、Koa&Nest)

Node.js知识体系涵盖核心基础、服务端开发、数据存储、进阶架构和工程化部署五大领域。核心模块包括fs(文件操作)、http(网络服务)、events(事件驱动)等,通过异步编程和事件循环实现高性能。Express作为主流Web框架,以中间件机制为核心,提供灵活的路由和模块化开发能力。学习路径可分为全栈开发、高性能架构和前端工程化三个方向,需掌握异步编程、数据库操作、API设计、性能优化等关键技术,并配合工程化工具实现自动化部署和质量保障。

警警的博客 1645

2016前端开发技术巡礼【摘自前端之巅】

前言 2016 年马上过去了,像过去六年中的每一年一样,Web前端领域又产生了“面目全非”而又“耳目一新”的变化,不但旧事物持续不断地被淘汰,新事物也难保坐久江山,大有岌岌可危之势。开源界如群雄逐鹿,不断生产新的概念、新的框架、新的工具,去年中一些流行的技术今年大多得到了进一步的演进和升级,活跃度非常高,却仍然不能保证前端的未来属于它们。在今年整体资本市场冷却的大环境下,to ...

diaojia9928的博客 612

初始node,用node进行数据库连接(mongodb)操作,node后端接口开发,返回前端请求响应

初始node,用node进行数据库连接(mongodb)操作,node后端接口开发,返回前端请求响应 一:node是什么? 1、node.js是 一个js的运行环境,node是一个后端环境,搭载的是js语言 2、它可用于服务端开发,这样可以避免我们开发语言的不同,导致开发量增加(全栈) 3、单线程,指主线程为一个单线程,可以是使用库来实现多线程(fork方法) 4、因为它是单线程,可以用于做高并发的应用 (高并发:它通常是指,通过设计保证系统能够同时并行处理很多请求)。但高密集型计算不使用 5、未来-&

丢失的Litte_志伟的博客 707

Node.js深度重学指南:现代应用场景与高性能架构实践

异步非阻塞I/O模型是构建高并发网络应用的核心原理之一,它通过事件驱动机制实现高效处理I/O密集型任务,显著提升系统吞吐量。这一技术价值在微服务架构和云原生环境中尤为突出,能够支撑API网关、实时通信和Serverless函数等多样化应用场景。Node.js基于V8引擎和统一的JavaScript技术栈,结合npm生态的丰富资源,为开发者提供了从BFF层到全栈开发的完整解决方案。本文聚焦Node.js的现代化演进,涵盖事件循环、流处理、集群管理等核心机制,并探讨如何结合TypeScript和NestJS框架

weixin_30947043的博客 363

ASP.NET Core必备笔试题(含答案)

1.如何在ASP.NET Core中激活Session功能? 首先要添加 session 包. 其次要在 config service 方法里面添加 session。 然后又在 configure 方法里面调用 usesession。 2.什么是中间件中间件在这里是指注入到应用中处理请求和响应的组件。是通过多个委托来嵌套形成的一个俄罗斯套娃! 或 中间件在这里是指注入到应用中处理请求和响应的组件。asp.net core 的中间件模型也是洋葱模型(和 node.js d Koa 一样

红目香薰 1224

2016前端开发技术巡礼

未来的Web前端开发体验一定是更丰富的,依托WebComponents的标准化组件体系,基于WebAssembly的高性能运行时代码,以及背靠HTTP/2协议的高速资源加载,前端工程师不必在性能上、兼容性上分散太多精力,从而可以专注于开发具备丰富式交互体验的下一代Web APP,可能是VR,也可能是游戏。

Mars_Fe工作室 505

[转] 2016前端开发技术巡礼

2016年马上过去了,像过去六年中的每一年一样,Web前端领域又产生了“面目全非”而又“耳目一新”的变化,不但旧事物持续不断地被淘汰,新事物也难保坐久江山,大有岌岌可危之势。开源界如群雄逐鹿,不断生产新的概念、新的框架、新的工具,去年中一些流行的技术今年大多得到了进一步的演进和升级,活跃度非常高,却仍然不能保证前端的未来属于它们。在今年整体资本市场冷却的大环境下,to B业务的...

weixin_34062469的博客 207

转载:2016前端开发技术巡礼

本文转自前端之巅,作者殷勇。 2016年马上过去了,像过去六年中的每一年一样,Web前端领域又产生了“面目全非”而又“耳目一新”的变化,不但旧事物持续不断地被淘汰,新事物也难保坐久江山,大有岌岌可危之势。开源界如群雄逐鹿,不断生产新的概念、新的框架、新的工具,去年中一些流行的技术今年大多得到了进一步的演进和升级,活跃度非常高,却仍然不能保证前端的未来属于它们。在今年整体资本市场冷却的大环境下,t...

weixin_33795806的博客 231
上一篇: 快点上车,前端异步编程发车了
下一篇: Redis6的持久化配置你知道多少?
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值