在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
相关产品推荐
相关产品推荐

