简体   繁体   中英

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

I'd like to reproduce javascript's Promise.race behavior in Python code. 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 . The example code below will print 1 and the exception will never be raised. The second for loop makes sure all of our pending coroutines are properly finished. 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. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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