[英]how to converting a for loop with await into asyncio.gather()
[英]How to not await in a loop with asyncio?
這是一個玩具示例,使用asyncio和aiohttp從多個網站下載主頁:
import asyncio
import aiohttp
sites = [
"http://google.com",
"http://reddit.com",
"http://wikipedia.com",
"http://afpy.org",
"http://httpbin.org",
"http://stackoverflow.com",
"http://reddit.com"
]
async def main(sites):
for site in sites:
download(site)
async def download(site):
response = await client.get(site)
content = await response.read()
print(site, len(content))
loop = asyncio.get_event_loop()
client = aiohttp.ClientSession(loop=loop)
content = loop.run_until_complete(main(sites))
client.close()
如果我運行它,我得到:
RuntimeWarning: coroutine 'download' was never awaited
但我不想等待它。
在扭曲我可以做:
for site in sites:
download(site)
如果我沒有明確地“收益”或向返回的Deferred添加回調,它只會在沒有阻塞或抱怨的情況下運行。 我無法訪問結果,但在這種情況下我不需要它。
在JS我可以這樣做:
site.forEarch(site){
donwload(site)
}
而且,它不會阻止,也不需要我的任何部分。
我找到了辦法:
async def main(sites):
await asyncio.wait([download(site) for site in sites])
但:
有更好的方法嗎?
要將協程安排為任務,請使用asyncio.ensure_future :
for site in sites:
coro = download(site)
future = asyncio.ensure_future(coro)
它取代了版本3.4.4中已棄用的函數asyncio.async 。
然后,您可以使用await
, asyncio.wait或asyncio.gather管理這些期貨。
- 找到它真的不明顯。 我很難記住。
關於協同程序的文檔確實很清楚asyncio.wait
的用途是什么。
- 很難理解它的作用。 “等待”似乎說“我阻止”,但沒有清楚地傳達它阻止整個協程列表完成。
再次,請參閱文檔。
- 你不能傳入一個生成器,它需要是一個真正的列表,我覺得在Python中真的不自然。
再次,請參閱文檔,特別是asyncio.as_completed
- 如果我只有一個等待的怎么辦?
它應該仍然有效。
- 如果我不想在我的任務上等待,並安排它們執行然后繼續我的其余代碼怎么辦?
然后你可以使用asyncio.ensure_furture
。 事實上, asyncio.wait
是asyncio.ensure_future
(和其他一些邏輯)的便利函數。
- 這種方式更加冗長扭曲和JS解決方案。
也許,但這不是一件壞事(從我的角度來看)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.