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

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

哈喽大家好!我是小三。今天更的是前端文章,小三前端比较菜,有什么地方写得不对大家可以留言或者联系我探讨修改哦。

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

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

我们先来看一下这个代码

  1. const Koa = require('koa'
  2. const app = new Koa() 
  3. //第一个中间件 
  4. app.use((ctx, next) => { 
  5.     console.log("第一个中间件", 1); 
  6.     next() 
  7.     console.log("第一个中间件", 2); 
  8. }) 
  9. //第二个中间件 
  10. app.use((ctx, next) => { 
  11.     console.log("第二个中间件", 3); 
  12.     next() 
  13.     console.log("第二个中间件", 4); 
  14. }) 
  15. //第三个中间件 
  16. app.use((ctx, next) => { 
  17.     console.log("第三个中间件", 5); 
  18.     console.log("第三个中间件", 6); 
  19. }) 
  20. app.listen(3000, () => { 
  21.     console.log("Koa已经开启在http://loclhost:3000"); 
  22. }) 

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

第一个中间件 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函数的,但是.....

  1. const Koa = require('koa'
  2. const app = new Koa() 
  3.     //第一个中间件 
  4. app.use((ctx, next) => { 
  5.         console.log("第一个中间件", 1); 
  6.         next() 
  7.         console.log("第一个中间件", 2); 
  8.     }) 
  9.     //第二个中间件 
  10. app.use((ctx, next) => { 
  11.         console.log("第二个中间件", 3); 
  12.         next() 
  13.         console.log("第二个中间件", 4); 
  14.     }) 
  15.     //第三个中间件 
  16. app.use(async(ctx, next) => { 
  17.     console.log("第三个中间件", 5); 
  18.     const axios = require("axios"
  19.     const res = await axios.get('http://www.baidu.com'
  20.     console.log(res); 
  21.     console.log('发送了axios请求'); 
  22.     console.log("第三个中间件", 6); 
  23. }) 
  24. app.listen(3000, () => { 
  25.     console.log("Koa已经开启在http://localhost:3000"); 
  26. }) 

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

中间省略....

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

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

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

  1. const Koa = require('koa'
  2. const app = new Koa() 
  3. //第一个中间件 
  4. app.use(async(ctx, next) => { 
  5.     console.log("第一个中间件", 1); 
  6.     await next() 
  7.     console.log("第一个中间件", 2); 
  8. }) 
  9. //第二个中间件 
  10. app.use(async(ctx, next) => { 
  11.     console.log("第二个中间件", 3); 
  12.     await next() 
  13.     console.log("第二个中间件", 4); 
  14. }) 
  15. //第三个中间件 
  16. app.use(async(ctx, next) => { 
  17.     console.log("第三个中间件", 5); 
  18.     const axios = require("axios"
  19.     const res = await axios.get('http://www.baidu.com'
  20.     console.log('发送了axios请求'); 
  21.     console.log("第三个中间件", 6); 
  22. }) 
  23. app.listen(3000, () => { 
  24.     console.log("Koa已经开启在http://loclhost:3000"); 
  25. }) 

运行代码我们可以看到

中间省略...

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

 

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

 

责任编辑:武晓燕 来源: 零零后程序员小三
相关推荐

2022-10-25 08:01:17

洋葱模型Koa

2023-07-30 15:14:19

Koa葱圈模型

2013-04-01 15:38:54

异步编程异步编程模型

2021-06-29 09:34:00

洋葱模型中间件

2016-11-22 16:57:30

koanode.jsjavascript

2023-01-12 11:23:11

Promise异步编程

2011-02-22 09:09:21

.NETAsync CTP异步

2011-02-22 08:49:16

.NET同步异步

2013-04-01 15:25:41

异步编程异步EMP

2023-10-30 23:25:48

FuturesGo语言

2015-09-16 15:11:58

C#异步编程

2021-03-22 08:45:30

异步编程Java

2023-06-13 13:39:00

多线程异步编程

2011-07-27 14:10:43

javascript

2020-11-02 08:51:57

中间件和洋葱模型

2024-02-07 11:44:20

NestJSRxJS异步编程

2020-10-15 13:29:57

javascript

2024-04-01 09:45:50

TAP模式.NET异步编程

2021-04-26 05:33:54

Python异步编程

2024-01-22 08:52:00

AQS双异步数据一致性
点赞
收藏

51CTO技术栈公众号