本文介绍了什么是Python异步代码中的Promise.race等效项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Python代码中重现javascript的Promise.race行为.我想同时运行一组协程,并在第一个协程完成后返回,获取其结果并取消/丢弃仍在运行的协程.

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.

推荐答案

您可以使用 asyncio.wait ,参数为 return_when 设置为 FIRST_COMPLETED .下面的示例代码将打印 1 ,并且永远不会引发异常.第二个for循环可确保正确处理所有待处理的协程.如果 raising_wait 协程首先完成,则在调用创建的Task对象的 result 方法后,将按照文档中的指定引发异常.最后要提到的是,将 asyncio.wait FIRST_COMPLETED 一起使用并不能保证如果协程几乎同时完成,我们将只完成一个Task

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

这篇关于什么是Python异步代码中的Promise.race等效项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 14:39