Что будет эквивалентно Promise.race в асинхронном коде Python? - PullRequest
0 голосов
/ 29 декабря 2018

Я хотел бы воспроизвести поведение JavaScript Promise.race в коде Python.Я хочу запустить группу сопрограмм одновременно и вернуться после завершения первой, получить ее результат и отменить / отменить результаты тех, которые еще работают.

1 Ответ

0 голосов
/ 29 декабря 2018

Вы можете использовать asyncio.wait с аргументом return_when, установленным в FIRST_COMPLETED.Приведенный ниже пример кода напечатает print 1, и исключение никогда не будет возбуждено.Второй цикл for гарантирует, что все наши ожидающие сопрограммы правильно завершены.Если сопрограмма raising_wait завершится первой, после вызова метода result созданного объекта Task будет сгенерировано исключение, как указано в документации.Последнее, что следует упомянуть, это то, что использование asyncio.wait с RETURN_FIRST не гарантирует, что у нас будет ровно одна задача в готовом наборе.

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