You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python异步IO:await asyncio.gather与create_task+wait的概念差异

Python异步IO:gather与wait的差异及事件循环写法解析

首先要明确:你看到的两种写法,核心差异是asyncio API的新旧风格,同时也涉及asyncio.gather和asyncio.wait这两个API的定位区别。

一、事件循环写法的新旧区别

  • 现代async/await风格(Python 3.7+推荐)
    不需要手动获取和管理事件循环,直接用asyncio.create_task创建任务,配合await等待任务完成:

    await asyncio.gather(
        asyncio.create_task(task("One", work_queue)),
        asyncio.create_task(task("Two", work_queue)),
    )
    

    这种写法依赖顶层的asyncio.run()来启动事件循环(比如入口函数用asyncio.run(main())),API更简洁,符合Python异步编程的现代范式。

  • 旧版显式事件循环风格
    需要手动获取事件循环实例,通过loop.run_until_complete()来驱动任务执行:

    ioloop = asyncio.get_event_loop()
    tasks = [ioloop.create_task(foo()), ioloop.create_task(bar())]
    wait_tasks = asyncio.wait(tasks)
    ioloop.run_until_complete(wait_tasks)
    

    这种写法在Python 3.7之前是标准用法,现在除非需要自定义事件循环策略(比如用uvloop替代默认循环),否则不推荐使用。

二、gather与wait的核心差异

1. asyncio.gather:高层级批量等待

  • 专注于等待所有任务完成并返回结果,返回的结果列表顺序和输入任务的顺序完全一致。
  • 自动处理协程到任务的包装(不过推荐手动用create_task显式创建任务,更清晰)。
  • 默认情况下,只要有一个任务抛出异常,会立即终止并传播异常,其他未完成的任务会被取消;可以通过return_exceptions=True参数让所有异常被收集到结果列表中,不中断其他任务。
  • 适合大多数常规场景:你只需要让一批任务并行执行,最后拿到所有结果,不需要额外的流程控制。

2. asyncio.wait:底层精细化控制

  • 返回一个元组(done, pending),分别包含已完成的任务集合和未完成的任务集合。
  • 支持通过return_when参数控制返回时机:
    • asyncio.ALL_COMPLETED:默认,所有任务完成后返回
    • asyncio.FIRST_COMPLETED:第一个任务完成就立即返回
    • asyncio.FIRST_EXCEPTION:第一个任务抛出异常就立即返回
  • 你可以对未完成的pending任务进行后续操作(比如取消、继续等待),还能结合timeout参数实现超时控制。
  • 适合需要精细化管理任务流程的场景:比如分批处理任务、实现超时机制、监听任务完成状态等。

三、总结

你的理解没错:

  • asyncio.gather(配合现代事件循环写法)适合简化批量任务的等待逻辑,代码简洁,满足大部分日常需求。
  • asyncio.wait(常出现在旧版写法中)适合精细化配置任务的执行策略,提供更灵活的控制能力。

现在优先使用现代async/await风格的写法,只有当需要特殊的任务控制逻辑时,才考虑使用asyncio.wait。

内容的提问来源于stack exchange,提问作者febqij

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:35:20