简体   繁体   English

什么是 Promise.race 在 Python 异步代码中的等价物?

[英]What would be Promise.race equivalent in Python asynchronous code?

I'd like to reproduce javascript's Promise.race behavior in Python code.我想在 Python 代码中重现 javascript 的 Promise.race 行为。 I want to run group of coroutines simultaneously and return when first one is done, get its result and cancel/discard results of the ones that are still running.我想同时运行一组协程并在第一个协程完成时返回,获取其结果并取消/丢弃仍在运行的协程的结果。

You can use asyncio.wait with the argument return_when set to FIRST_COMPLETED .您可以将asyncio.wait与参数return_when设置为FIRST_COMPLETED The example code below will print 1 and the exception will never be raised.下面的示例代码将打印1并且永远不会引发异常。 The second for loop makes sure all of our pending coroutines are properly finished.第二个 for 循环确保我们所有挂起的协程都正确完成。 If raising_wait coroutine finishes first, after calling the result method of the created Task object, the exception will be raised as specified in documentation.如果raising_wait协程先完成,则在调用创建的 Task 对象的result方法后,将按照文档中的说明引发异常。 Last thing to mention is that, that using asyncio.wait with FIRST_COMPLETED doesn't guarantee that we will have exactly one Task in done set if the couroutines finish in almost same time.最后要提到的是,如果协程几乎在同一时间完成,使用asyncio.waitFIRST_COMPLETED并不能保证我们将有一个任务完成。

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM