在学习asyncio时我正在尝试这段代码:
import asyncio
from asyncio.coroutines import coroutine
@coroutine
def coro():
counter: int = 0
while True:
print("Executed" + str(counter))
counter += 1
yield
loop = asyncio.get_event_loop()
loop.run_until_complete(coro())
loop.run_forever()
print("Finished!")
我期待协程只执行一次,因为它包含一个yield并且应该已经将控制权返回给调用者。我期待的输出是:
Executed 0
Finished!
我期待这种行为,因为我认为循环将永远运行协程一旦每个“帧”在每次执行后返回到调用者(类似于后台线程但是以合作的方式)。但相反,它会永远运行协程而不返回?输出如下:
Executed 0
Executed 1
Executed 2
Executed 3
...
有人能解释为什么会发生这种情况而非我的期望吗?
干杯。
答案 0 :(得分:1)
你有几个问题。当您致电run_until_complete
时,它会等待coro
完成,然后再转到run_forever
来电。正如您所定义的那样,coro
永远不会完成。它包含一个无限循环,无法突破循环。如果要继续执行应用程序中的下一步,则需要在循环内的某处break
或return
。
但是,一旦你完成了这个,你的下一个电话就是run_forever
,就像它的名字所示,它会永远运行。在这种情况下,它没有任何事情要做,因为你没有安排事件循环。
我期待协程只执行一次,因为它包含一个yield并且应该已经将控制权返回给调用者。
回顾一下你的协程没有收益的事实,等待(或根据你选择使用的语法而产生)并不会将控制权交还给run_until_complete
或run_forever
的来电者。它将控制权返回给事件循环,以便它可以检查已经等待并准备恢复的任何其他内容。