当前位置: 首页 > 科技观察

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

时间:2023-03-14 22:27:12 科技观察

大家好!我是小三今天的更新是关于前端的文章。小三的前端比较好。如果有不对的地方可以留言或者联系我一起讨论修改。koa框架的业务流程是一个完整的异步编程模型,通过ctx上下文对象贯穿http的上下游。对我们来说最重要的是理解洋葱模型。先看一个经典的洋葱图来认识一下先看这段代码constKoa=require('koa')constapp=newKoa()//第一个中间件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("第三个中间件middleware",5);console.log("第三个中间件",6);})app.listen(3000,()=>{console.log("Koa已经在http://loclhost:3000打开");})我们运行这段代码在浏览器中打开,返回控制台可以看到并打印出第一个中间件1第二个中间件3第三个第一个中间件5第三个中间件6第二个中间件4第一个中间件2可以看到这段代码,它的执行效果是135642,也就是说,就像第一个中间件把第二个包裹起来,第三个中间件包裹第二个d中间件。调用next时,会回头执行第二个中间件,结束后继续执行第一个。所以他的命令应该是这样的。看到上图,相信大家已经很明白了。那么下面我们就要用到asyncawait这个语法糖了。这里简单介绍下async函数。它是生成器函数的语法糖。可以通过yield(中文翻译动词提供,暂时叫他提供)关键字来提供,也就是使用函数暂停执行流程,提供改变执行流程的可能,从而为异步提供解决方案编程。async函数就是把生成器函数的*换成async,把yield换成await。简单来说,async/await是异步编程中编写回调函数的另一种方法。目前为止就这样了。我将在下一篇文章中详细介绍async。await函数,在async函数执行时多说一句,如果遇到await,会先暂停执行,等待触发的异步操作完成,再恢复??async函数的执行,并返回解析后的值。我们再看看洋葱模型,然后我在第三个中间件里面加了一个axios请求,因为是异步操作,所以要在前面加一个async,然后在request前面加一个await,这样我们可以得到get请求的结果。如果没有添加,它会返回一个Promise对象。这里添加了asyncawait函数,但是...constKoa=require('koa')constapp=newKoa()//第一个中间件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);constaxios=require("axios")constres=awaitaxios.get('http://www.baidu.com')console.log(res);console.log('axios请求已发送');console.log("第三个中间件",6);})app.listen(3000,()=>{console.log("Koahasbeenopenedathttp://localhost:3000");})我们通过打印结果ourself,可以看到中间省略了....可以看出虽然我们取到了res结果,但是它的打印顺序发生了变化,就是遇到await后会暂停执行,恢复执行async函数并返回解析after触发的异步操作完成。价值。但是这样不符合我们想要的结果。我们想要的是按照原来的顺序执行。那么,为了保证洋葱模型,我们应该改成如下,在之前的代码中加入asyncawait,控制在我们预期之前的情况。里面。constKoa=require('koa')constapp=newKoa()//第一个中间件app.use(async(ctx,next)=>{console.log("第一个中间件",1);awaitnext()console.log("第一个中间件",2);})//第二个中间件app.use(async(ctx,next)=>{console.log("第二个中间件",3);awaitnext()console.log("第二个中间件",4);})//第三个中间件app.use(async(ctx,next)=>{console.log("第三个中间件",5);constaxios=require("axios")constres=awaitaxios.get('http://www.baidu.com')console.log('axios请求已发送');console.log("第三个中间件",6);})app.listen(3000,()=>{console.log("Koahasbeenopenedathttp://loclhost:3000");})运行代码,我们可以看到中间有Omit...所以我们在写中间件函数的时候,一般把中间件变成asyncawait函数,这样洋葱模型就不会因为异步编程而无法控制和不合理了。以上是我自己的理解。如果还有更多的地方我说不清楚,大家可以留言告诉我,我会好好学习的,大家一起交流,互相学习。希望大家不要吝啬,求求你们了。