勘误,昨天文章中的知识性错误

简介: 勘误,昨天文章中的知识性错误

摄影:产品经理暴雨前的宁静

在昨天的文章里面,我说asyncio.create_task(异步函数())并没有真正运行。

这犯了一个知识性错误。实际上这样写,异步函数里面的代码运行了。例如:

当我们执行异步函数()时,它返回的是一个coroutine对象,此时这个异步函数里面的代码是没有运行的。但是当把 coroutine 对象传入asyncio.create_task()时,异步函数里面的代码就已经开始运行了。

但是,如果我们直接把昨天代码里面的 asyncio.gather 去掉,也会导致报错,如下图所示:


可以看到,两个内部不含 await 的异步函数成功执行了,但是调用 aiohttp 的两个异步函数却报错了。

这是由于,当我们的代码运行到第32行时,它并不会停下来,而是直接退出了 aiohttp 的缩进,此时,aiohttp 的 Session 就已经关闭了。过了一会,网站请求的返回才回来,可是由于 Session 关闭,于是导致报错。

在这个例子里面,由于我们知道哪个异步任务最耗时,所以我们可以人工等待它:

此时程序就能正常运行了。这里看起来就像调用多线程里面的.join()一样。当我们调用 await 任务的时候,程序一定会在第33行等待5秒延迟的这个任务。一开始的时候我们有4个异步任务,asyncio 在这四个任务之间调度。后来前3个任务都结束了,asyncio 就直接等着最后一个任务结束。等到5秒延迟返回了,程序才会退出 aiohttp 的缩进。所以程序就不会报错了。

但在实际使用中,我们可能并不知道哪个异步任务耗时最久,所以有两种解决方案:

第一种是模拟多线程的情况,写一个循环,执行一个很长的睡眠时间,或者直接死循环:

但这种方案有个弊端,就是可能真正的任务已经全部运行完了,你循环的时间还没有结束。

第二种方案,跟昨天一样,使用asyncio.gather,这样可以保证所有任务运行完成以后,立刻返回。并且,asyncio.gather不仅能接受异步任务,也能直接接收coroutine对象:

当我们不使用asyncio.gather时,其实代码的运行逻辑就跟 JavaScript 原生的异步相差不大了。

最后,感谢🐳klew指出昨天文章中的问题。

目录
相关文章
机房重构遇到的BUG
机房重构遇到的BUG
102 0
|
机器学习/深度学习 算法 编译器
明天省赛,我都还不太熟悉Dev - C++,怎么切换成C++11了?它的报错看不懂呀,那花八分钟看看这篇文章吧~解决你的困惑。
明天省赛,我都还不太熟悉Dev - C++,怎么切换成C++11了?它的报错看不懂呀,那花八分钟看看这篇文章吧~解决你的困惑。
1609 0
明天省赛,我都还不太熟悉Dev - C++,怎么切换成C++11了?它的报错看不懂呀,那花八分钟看看这篇文章吧~解决你的困惑。
|
开发者 微服务
项目第二天内容介绍 | 学习笔记
快速学习 项目第二天内容介绍
|
Java 中间件 程序员
最网最全bug定位套路,遇见bug再也不慌了
最网最全bug定位套路,遇见bug再也不慌了
377 0
|
Java 程序员
学妹问我Java异常是怎么回事,讲了半夜才明白,速度收藏!!!记得点赞和关注
异常是Java开发中常见的,也是程序最不愿意看到的,因为有异常基本上就代表我们写的代码有bug,很烦,游戏服务端有异常上报系统,每当半夜收到异常上报都慌的一笔。今天就扒一扒异常,开始走起。
160 0
学妹问我Java异常是怎么回事,讲了半夜才明白,速度收藏!!!记得点赞和关注
|
网络协议 Linux
被鹅厂搞懵逼了(更正)
在 FIN_WAIT_2 状态下如何处理乱序的 FIN 报文
被鹅厂搞懵逼了(更正)
|
监控 Java 索引
昨天面试居然聊了半个多小时的异常处理
大风吹去了往日的雾霾,阳光透过窗户照进来,透过窗户可以看到远处的山脉与蓝天相接,这可比我那永远见不到阳光的出租屋好多了。渐渐走进的脚步声打断了我的思绪,一位小姐姐坐在了面前,甜甜的香水味立刻钻进了我的鼻孔。 小姐姐微笑地说:”您好,我是今天的面试官,那么开始吧?“ 我收起直勾勾的眼睛,说:“好的。” 小姐姐说:“在Java的异常处理中有两大组成要素:抛出异常和捕获异常。那么抛出异常可以分为哪两种呢?” 我立刻回答到:
164 0
|
XML 存储 数据可视化
做时间的朋友 —— 用印象笔记打造时间记录工具
做时间的朋友 —— 用印象笔记打造时间记录工具
671 0
|
Java Spring
遇到 400、500 错误千万不要慌!
很多人都会在平时开发过程中遇到400或500异常,并且也没有走到服务端controller中,就变得有些不知所措。 我们知道SpringMVC从DispatchServlet开始接收与分发请求,从入口开始debug,还能找不到问题所在么? 从DispatchServlet的doDispatch()方法开始处理请求:
418 0