【问题标题】:Process list of async tasks immediately upon each task's completion每个任务完成后立即处理异步任务列表
【发布时间】:2018-11-22 06:23:18
【问题描述】:

如何在任务完成后立即处理async 任务列表的结果?

例如,以下内容应显示首先加载的页面:

urls = ['stackoverflow.com', 'google.com']
tasks = [asyncio.create_task(fetch_page(x)) for x in urls]

for page in asyncio.give_me_results_ASAP(tasks):
    print(page.url)

由于 google 加载速度更快,我希望将其打印出来:

google.com
stackoverflow.com

【问题讨论】:

  • 可能是简单的方法是在获取页面中添加打印?
  • 你能解释一下你的优先事项吗?订单对您来说是最重要的还是即时性?如果即时性是主要目标,为什么它是目标?即使牺牲了订单,您是否愿意接受能够更快完成工作的解决方案?
  • @BearBrown 说得好。虽然我想我有某种异步迭代器。 (这样,我可以tee 以线程安全的方式输出结果,但也可以立即处理它们。)
  • @user2357112 即时性。订购无关紧要。

标签: python asynchronous


【解决方案1】:

asyncio.as_completed 正是为此而设计的,它按照任务完成的顺序返回一个协程迭代器。迭代器返回的第一个协程将对应第一个完成的任务,您可以在每个协程上await获取任务的结果。

# With Python 3.8+
import asyncio
import time

async def fetch_page(url):
    reponse_time = 0.1 if url == 'google.com' else 0.8
    await asyncio.sleep(reponse_time)
    return url

async def main():
    urls = ['stackoverflow.com', 'google.com']
    tasks = [asyncio.create_task(fetch_page(x)) for x in urls]

    for coro in asyncio.as_completed(tasks):
        print(f"{time.time():.3f}", await coro)

if __name__ == '__main__':
    asyncio.run(main())

产生:

1600821288.178 google.com
1600821288.280 stackoverflow.com

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
相关资源
最近更新 更多