'await future' 和 'await asyncio.wait_for(future, None)' 有区别吗?

Is there a difference between 'await future' and 'await asyncio.wait_for(future, None)'?

对于 python 3.5 或更高版本,直接将 await 应用于未来或任务与使用 asyncio.wait_for 包装它之间有什么区别吗?该文档不清楚何时适合使用 wait_for,我想知道它是否是旧的基于生成器的库的遗迹。下面的测试程序看起来没有区别,但这并不能真正证明什么。

import asyncio

async def task_one():
    await asyncio.sleep(0.1)
    return 1

async def task_two():
    await asyncio.sleep(0.1)
    return 2

async def test(loop):
    t1 = loop.create_task(task_one())
    t2 = loop.create_task(task_two())

    print(repr(await t1))
    print(repr(await asyncio.wait_for(t2, None)))

def main():
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(test(loop))
    finally:
        loop.close()

main()

不幸的是,python 文档在这里有点不清楚,但是如果您查看 sources,它非常明显:

await 相反,协程 asyncio.wait_for() 只允许等待有限的时间,直到 future/task 完成。如果在此时间内未完成,则会引发 concurrent.futures.TimeoutError

这个超时可以指定为第二个参数。在您的示例代码中,此 timeout 参数是 None,它导致 完全 与直接应用 await/yield from 相同的功能。

wait_for 提供了另外两个功能:

  1. 允许定义超时,
  2. 让你指定循环

你的例子:

await f1
await asyncio.wait_for(f1, None)  # or simply asyncio.wait_for(f1)

除了调用额外包装器的开销 (wait_for),它们是相同的 (https://github.com/python/cpython/blob/master/Lib/asyncio/tasks.py#L318)。

两者awaits都会无限期地等待结果(或异常)。在这种情况下,普通 await 更合适。

另一方面,如果您提供超时参数,它将等待有时间限制的结果。如果它花费的时间超过超时时间,它将引发 TimeoutError 并且未来将被取消。

async def my_func():
    await asyncio.sleep(10)
    return 'OK'

# will wait 10s 
await my_func()

# will wait only 5 seconds and then will raise TimeoutError
await asyncio.wait_for(my_func(), 5)

另一件事是循环参数。在大多数情况下你不应该被打扰,用例是有限的:为测试注入不同的循环,运行 其他循环......

此参数的问题是,所有后续 tasks/functions 也应该传递该循环...

更多信息https://github.com/python/asyncio/issues/362