我想在Python代码中重现javascript的Promise.race行为。我想同时运行一组协程,并在第一个协程完成后返回,获取其结果并取消/丢弃仍在运行的协程。
答案 0 :(得分:0)
您可以在参数return_when
设置为FIRST_COMPLETED
的情况下使用asyncio.wait。下面的示例代码将打印1
,并且永远不会引发异常。第二个for循环可确保正确处理所有待处理的协程。如果raising_wait
协程首先完成,则在调用创建的Task对象的result
方法之后,将按照文档中的指定引发异常。最后要提到的是,将asyncio.wait
与RETURN_FIRST
一起使用并不能保证我们将在完成的任务集中只有一个Task。
from contextlib import suppress
import asyncio
async def wait(t):
await asyncio.sleep(t)
return t
async def raising_wait(t):
await asyncio.sleep(t)
raise TimeoutError("You waited for too long, pal")
loop = asyncio.new_event_loop()
done_first, pending = loop.run_until_complete(
asyncio.wait(
{wait(1), raising_wait(2), wait(3)}, return_when=asyncio.FIRST_COMPLETED
)
)
for coro in done_first:
try:
print(coro.result())
except TimeoutError:
print("cleanup after error before exit")
for p in pending:
p.cancel()
with suppress(asyncio.CancelledError):
loop.run_until_complete(p)
loop.close()