【发布时间】:2021-03-19 15:21:31
【问题描述】:
我是 python 新手,正在尝试学习 asyncio 模块。我对从异步任务中获取返回值感到沮丧。有一个帖子here 谈到了这个话题,但它无法分辨哪个任务返回哪个值(假设某个网页响应比另一个更快)。
下面的代码尝试同时获取三个网页,而不是一个一个地进行。
import asyncio
import aiohttp
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
assert resp.status == 200
return await resp.text()
def compile_all(urls):
tasks = []
for url in urls:
tasks.append(asyncio.ensure_future(fetch(url)))
return tasks
urls = ['https://python.org', 'https://google.com', 'https://amazon.com']
tasks = compile_all(urls)
loop = asyncio.get_event_loop()
a, b, c = loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
print(a)
print(b)
print(c)
首先,虽然它确实打印了一些 html 文档,但它遇到了 Runtimeerror:RuntimeError: Event loop is closed。
第二,问题是:这真的保证a,b,c会依次对应urls[0],url[1],urls[2]网页的urls列表吗? (我认为异步任务的执行不能保证这一点)。
第三,任何其他更好的方法或在这种情况下我应该使用队列吗?如果是,怎么做?
任何帮助将不胜感激。
【问题讨论】:
-
使用
await将暂停函数的执行,直到它返回一些东西,但不会阻止其他async函数运行。如果您是 python 新手,我不建议您使用asyncio进行多处理,因为它确实很复杂,最适合更有经验的人。 -
另外,你的问题很奇怪。 “Python 网页”是什么意思?
-
必须使用工作所需的 asyncio,这就是我需要学习它的原因。我已经修改了我的问题表达,对此感到抱歉。
-
我明白了。但是“Python 网页”是什么意思?
-
我无法重现您观察到的
RuntimeError。是的,无论它们完成的顺序如何,结果都将对应于 URL 的序列。