我剪下了以下代码:
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
async with session.get("https://hub.dummyapis.com/delay?seconds=1") as r:
print("Here!")
text = await r.text()
print(text)
asyncio.run(main())
我调用的网址只是等待一秒钟,然后返回一个
200
。
我以为
Here!
会立即打印,然后 1 秒会过去(或者可能会多一点,包括发送和接收请求的开销),然后文本将被打印。毕竟,我只是在 await
声明之后才 print("Here!")
。但事实并非如此,Here!
仅在1秒后才被打印。所以我猜 async with session.get(...) as r
被阻塞了?我的问题:
aiohttp
的实现细节,还是我在这里误解了async
?我可以解锁session.get(...) as r
吗?这可以用
aiohttp
吗?
基本上这是一个内部实现。让我们研究一下 aiohttp 实现并从以下代码行开始
async with session.get("https://hub.dummyapis.com/delay?seconds=1") as r:
ClientSession
的Get方法返回一个名为
_RequestContextManager
here的上下文管理器。如果你检查这个上下文管理器,它是从另一个名为 _BaseRequestContextManager
的上下文管理器继承的。 在这个上下文管理器的 __aenter__
中,它基本上等待请求的响应并返回响应。基本上,通过这一行,您已经向服务器发出了请求,并且服务器等待 1 秒才能获得响应。所以“这里!”是很正常的。 1秒后打印,因为上下文管理器内部的代码是在获得响应后执行的。如果您检查 text
的
ClientResponse
方法,您可以看到该方法仅获取响应正文并对其进行解码。