【问题标题】:What would be Promise.race equivalent in Python asynchronous code?Python 异步代码中的 Promise.race 等价物是什么?
【发布时间】:2018-12-29 06:33:04
【问题描述】:

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

【问题讨论】:

    标签: javascript python asynchronous promise python-asyncio


    【解决方案1】:

    您可以使用 asyncio.wait 并将参数 return_when 设置为 FIRST_COMPLETED。下面的示例代码将打印1,并且永远不会引发异常。第二个 for 循环确保我们所有待处理的协程都正确完成。如果 raising_wait 协程首先完成,在调用创建的 Task 对象的 result 方法后,将按照文档中的说明引发异常。最后要提到的是,如果 couroutines 几乎在同一时间完成,使用 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()
    task_set = set()
    
    task_set.add(loop.create_task(wait(1)))
    task_set.add(loop.create_task(raising_wait(2)))
    task_set.add(loop.create_task(wait(3)))
    
    done_first, pending = loop.run_until_complete(
        asyncio.wait(task_set, 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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 2012-06-03
      • 2019-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-18
      相关资源
      最近更新 更多