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

在Tokio中等待两个Future中的任意一个完成

如何等待多个Future中第一个完成的任务

当然有可行的实现方式,几乎所有支持异步编程的主流语言都提供了原生API来处理这类“等待首个完成异步任务”的场景,不用自己手动写轮询逻辑,下面举几个常见语言的具体实现:

Python 实现

Python的asyncio库提供了两种便捷方式:

方式1:使用asyncio.wait

通过设置return_when=asyncio.FIRST_COMPLETED,可以直接获取第一个完成的任务,同时还能拿到未完成的任务列表,方便后续取消以节省资源:

import asyncio

async def task1():
    await asyncio.sleep(2)
    return "任务1完成"

async def task2():
    await asyncio.sleep(1)
    return "任务2完成"

async def main():
    done, pending = await asyncio.wait(
        [task1(), task2()],
        return_when=asyncio.FIRST_COMPLETED
    )
    # 取出首个完成任务的结果
    first_result = next(iter(done)).result()
    print(f"第一个完成的任务:{first_result}")
    
    # 可选:取消未完成的任务,避免占用资源
    for task in pending:
        task.cancel()

asyncio.run(main())

方式2:使用asyncio.as_completed

这个方法会返回一个迭代器,迭代器会依次产出完成的任务,取第一个结果后直接退出循环即可:

import asyncio

async def task1():
    await asyncio.sleep(2)
    return "任务1完成"

async def task2():
    await asyncio.sleep(1)
    return "任务2完成"

async def main():
    tasks = [task1(), task2()]
    for completed_task in asyncio.as_completed(tasks):
        result = await completed_task
        print(f"第一个完成的任务:{result}")
        # 获取首个结果后直接终止循环,忽略剩余任务
        break

asyncio.run(main())

JavaScript/Node.js 实现

Node.js里直接用Promise.race()方法,它会返回第一个完成的Promise的结果(无论成功还是失败):

function task1() {
    return new Promise(resolve => setTimeout(() => resolve("任务1完成"), 2000));
}

function task2() {
    return new Promise(resolve => setTimeout(() => resolve("任务2完成"), 1000));
}

async function main() {
    const firstResult = await Promise.race([task1(), task2()]);
    console.log(`第一个完成的任务:${firstResult}`);

    // 如果需要只等待第一个成功完成的任务(忽略失败的),可以包装每个Promise
    function wrapPromise(promise) {
        return promise.catch(() => null); // 失败时返回null作为标记值
    }
    const firstSuccessResult = await Promise.race([wrapPromise(task1()), wrapPromise(task2())]);
    if (firstSuccessResult) {
        console.log(`第一个成功完成的任务:${firstSuccessResult}`);
    }
}

main();

注意事项

  • 如果你不需要未完成的任务继续执行,记得主动取消它们(比如Python的task.cancel(),JavaScript可通过AbortController终止支持取消的Promise),避免浪费系统资源。
  • 部分语言的“首个完成”API会响应任务的失败状态,如果只想等待成功完成的任务,需要额外对任务进行包装处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:05:12