在 Python 核心开发人员 Brett Cannon 的一篇文章《 How the heck does async/await work in Python 3.5?》中提到:
One very key point I want to make about the difference between a generator-based coroutine and an async one is that only generator-based coroutines can actually pause execution and force something to be sent down to the event loop.
之后总结中还有一句:
You can only make a coroutine call chain pause with a generator-based coroutine.
对应的翻译版在这里:《[译] Python 3.5 协程究竟是个啥》,引用如下:
关于基于生成器的协程和 async 定义的协程之间的差异,我想说明的关键点是只有基于生成器的协程可以真正的暂停执行并强制性返回给事件循环。
你只能通过基于生成器的定义来实现协程的暂停。
在我的理解中,基于生成器的协程使用 yield from 语句,async 定义的协程使用 await 语句,虽然两者可以接受的对象不同(具体原文中有详细描述),但是两者的作用应该是一样的啊:都是暂停当前协程的执行,转交出执行权,直到 yield from 或者 await 的对象执行完成后再返回,继续执行后面的语句。
对此,PEP-492 也有提,下面是其中提到的例子:
async def read_data(db):
data = await db.fetch('SELECT ...')
...
await
, similarly to yield from , suspends execution of read_data coroutine until db.fetch awaitable completes and returns the result data.
It uses the yield from implementation with an extra step of validating its argument.
也就是说,await
应该使用了yield from
类似的实现,作用也是暂停当前执行流程。那么,为啥await
不能“真正的暂停执行并强制性返回给事件循环”?
一个脑洞:难道是因为await
将执行权转交给了后面的对象,但是并没有转交给作为调度者的消息循环?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.