想象一下以下非常常见的情况:您编写了一个又长又复杂的函数,并意识到一些代码应该提取到一个单独的函数中以便重用和/或可读。通常,这个额外的函数调用不会改变程序的语义。
但是,现在假设您的函数是一个协程,并且您要提取的代码至少包含一个异步调用。现在,将其提取到一个单独的函数中,通过插入一个新点来突然改变程序语义,在该点上协程产生,事件循环进行控制,并且可以在其间安排任何其他协程。
之前的例子:
async def complicated_func():
foo()
bar()
await baz()
之后的示例:
async def complicated_func():
foo()
await extracted_func()
async def extracted_func():
bar()
await baz()
在之前的例子中,complicated_func
保证在调用之间不会被暂停foo()
并打电话bar()
。重构后,这种保证就消失了。
我的问题是:可以打电话吗extracted_func()
这样它就会立即执行,就好像它的代码是内联的一样?或者是否有其他方法可以在不更改程序语义的情况下执行此类常见的重构任务?
重构后,这种保证就消失了。
其实不是。
是否可以调用extracted_func(),使其立即执行,就好像其代码是内联的一样?
情况已经如此了。
await some_coroutine()
意思是some_coroutine
可能会将控制权交还给事件循环,但直到它真正等待未来(例如某些 I/O 操作)时才会这样做。
考虑这个例子:
import asyncio
async def coro():
print(1)
await asyncio.sleep(0)
print(3)
async def main():
loop.call_soon(print, 2)
await coro()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
注意如何2
之间打印1
and 3
正如预期的那样。
这也意味着可以通过编写以下代码来冻结事件循环:
async def coro():
return
async def main():
while True:
await coro()
在这种情况下,事件循环永远没有机会运行另一个任务。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)