为什么aiohttp响应的json()方法需要await?

问题描述 投票:0回答:2

我不明白为什么需要等待

resp.json()
。据我了解,async/await 在处理 I/O 时很有用。但是,当我在下面的示例中调用 resp.json() 时,Web 请求是否尚未使用上面行中的 session.get() 进行处理?

async with session.get('https://api.github.com/events') as resp:
    print(await resp.json())
python-3.x python-asyncio aiohttp
2个回答
5
投票

但是当我在下面的示例中调用 resp.json() 时,上面的行中的 Web 请求是否还没有被 session.get() 处理过?

不,它只读取 HTTP 标头,要获取响应正文,您需要读取响应的其余部分。

这非常有用,因为如果服务器返回了错误的 HTTP 代码,您可以检查 HTTP 标头并避免读取响应的其余部分。

另一个例子:如果您期望响应正文很大,您可以分块读取它以避免 RAM 过度使用(请检查此处的注释)。


0
投票

我陷入了困境,所以让我解释一下。

你说得对,因为到 JSON 的转换不受 I/O 限制,而且也几乎不受 CPU 限制(除非响应正文非常大)。

但是,在

aiohttp
的示例中,等待的并不是到 JSON 的转换,尽管它在提供的界面中出现误导性地出现。

aiohttp 的作用是,即使服务器一次性返回所有内容(状态代码、标头和正文)(假设非流式情况,这就是 HTTP 的工作原理),客户端也可以将所有内容缓冲到内存中,并且分步阅读。因此,它可以首先读取状态代码,然后根据其值,可以继续或不执行其他步骤。从技术上讲,每个步骤都是一个单独的 I/O 操作,尽管我们通常不认为从内存读取是瓶颈,因为它非常快。

此外,如果响应正文很大,它可能还没有完全到达,因此额外的步骤也会涉及网络 I/O。

这种分离对于大型响应非常有用,但大多数情况下只会增加异步开销。请记住,异步编程应该只在有意义的地方使用,如果不是每个函数默认都是可等待的,并且我们不会有 async/await 关键字。

虽然这是 aiohttp 中的一个决定,所以你无能为力。最终,您获得的总比您失去的要多(与在整个项目中使用

requests
相比),因此您可能应该接受这种权衡。

© www.soinside.com 2019 - 2024. All rights reserved.