【问题标题】:What is the point of having to put await in front of each async function in Python?必须在 Python 中的每个异步函数前面放置 await 有什么意义?
【发布时间】:2021-11-06 03:08:51
【问题描述】:

在 Python 中,我们需要在每个协程对象之前添加一个 await 关键字,以便事件循环调用它。但是当我们输入await 时,它会使调用阻塞。因此,我们最终会做与阻塞方式相同的事情。有这样的用途有什么意义?

https://www.aeracode.org/2018/02/19/python-async-simplified/

https://stackabuse.com/python-async-await-tutorial/

【问题讨论】:

  • 这能回答你的问题吗? How does asyncio actually work?
  • "但是当我们输入await 时,它会使呼叫阻塞。"什么让你有那个想法?例如,第一个链接说“协程同步运行,直到它们遇到等待,然后它们暂停,放弃对事件循环的控制,并且可能发生其他事情。
  • await 被调用的行之后的以下行必须等待 promise 解决。所以它阻止了它的范围,我错了吗?所以不像 JS,我们不需要等待,我们需要阻塞每个异步函数的作用域。这减少了同样的事情。我很困惑。
  • await 的重点是 other 协程(“范围”)可以在当前协程(“块”)挂起时运行。
  • 这能回答你的问题吗? How does asyncio actually work?

标签: python async-await


【解决方案1】:

使用await 不会使调用同步。让它看起来像“正常”顺序代码只是语法糖。但是虽然函数调用的结果是awaited,但事件循环仍然在后台继续。

例如,以下代码执行两次foo(),这将是awaitsleep。但即使它使用await,第二个函数调用也会在第一个函数完成之前执行。 IE。它并行运行。

import asyncio

async def main():
    print('started')
    await asyncio.gather(
        foo(),
        foo(),
    )

async def foo():
    print('starting foo')
    await asyncio.sleep(0.1)
    print('foo finished.')

asyncio.run(main())

打印:

started
starting foo
starting foo
foo finished.
foo finished.

【讨论】:

    【解决方案2】:

    await 使调用本地阻塞,但“等待”是通过异步函数传输的(它本身是等待的),这样当它到达 reactor 可以将整个任务移至候补名单,然后运行其他任务。

    此外,您不需要await,您也可以spawn 协程(到一个单独的任务,您可能会或可能不会等待),或者使用“未来的组合器”(asyncio.gatherasyncio.wait,...)与其他组合同时运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 2020-10-04
      • 1970-01-01
      • 2022-01-23
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多