Вы можете использовать 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()