Skip to content

实验 5:按完成顺序处理结果

gather() 会按输入顺序返回结果。这在很多时候很好用。但有些场景里,谁先回来就先处理谁更合适,比如先展示最快返回的搜索结果。

运行:

bash
python3 examples/asyncio_demos/05_gather_as_completed.py

gather 的顺序

示例里的三个任务耗时不同:

python
JOBS = [
    ("profile", 0.35),
    ("orders", 0.10),
    ("recommendations", 0.20),
]

gather() 的结果仍然按 JOBS 的顺序返回:

python
results = await asyncio.gather(*(fetch(name, delay) for name, delay in JOBS))

这适合“最后统一组装结果”的代码。

as_completed 的顺序

如果想谁先完成就先处理谁,用 asyncio.as_completed()

python
tasks = [asyncio.create_task(fetch(name, delay)) for name, delay in JOBS]

for completed in asyncio.as_completed(tasks):
    result = await completed
    print(result)

这段代码会先拿到 orders,再拿到 recommendations,最后才是 profile

怎么选

你想要什么写法
等一批任务全部完成,再按输入顺序拿结果gather()
哪个任务先完成,就先处理哪个as_completed()
一组任务属于同一个操作,失败时要一起收尾TaskGroup

这三个工具都能跑多个任务,但用途不一样。不要只因为“能并发”就混用。

小练习

  1. profile 的耗时改成 0.05,观察两种写法的输出。
  2. JOBS 里再加一个 ("reviews", 0.05),观察两个版本的输出顺序。
  3. as_completed 循环里打印当前时间,确认结果确实是一个个出来的。

面向学习目的的 Python asyncio 中文教程与 mini_asyncio 教学运行时。