2 回答

TA贡献1821条经验 获得超6个赞
等待调用,然后在返回类的实例上调用该方法。
async def start_doing():
await asyncio.sleep(1)
return Dummy
async def do_something():
thing = await start_doing()
return thing().method()
当等待对象已经等待并且我的对象已准备好时,我应该如何在将来调用对象方法?如何安排它在未来被调用?
看看我能不能弄对。
当您创建任务do_something时,它会被安排。
最终事件循环决定让我们do_something开始。
do_something呼叫start_doing并等待它。
在do_something等待的过程中,事件循环将控制权从它手中夺走,让其他事情发生。
在某些时间点start_doing被调度,开始,完成等待/休眠,返回对象
在等待/睡眠部分控制可能已通过事件循环转移到其他任务
最终在do_something等待事件循环完成后将控制权/焦点交还给它。
暗示其他计划任务已经完成或正在等待某事。
我真的不知道调度算法是什么,我认为它是一个循环事件,但它可能比这更智能。

TA贡献1815条经验 获得超10个赞
要进一步扩展@wwii的答案并解决有关阻塞风险的担忧,await
您可以使用以下功能f
:
import time
from datetime import datetime
import asyncio
start = datetime.now()
async def f(x, block_for=3):
print(f"{x} IN {ellapsed_time()}s")
time.sleep(block_for)
print(f"{x} AWAIT {ellapsed_time()}s")
await asyncio.sleep(x)
print(f"{x} OUT {ellapsed_time()}s")
def ellapsed_time():
return (datetime.now() - start).seconds
asyncio.create_task(f(2))
asyncio.create_task(f(1))
哪个产生:
2 IN 0s
2 AWAIT 3s
1 IN 3s
1 AWAIT 6s
2 OUT 6s
1 OUT 7s
Untilawait被调用,f(2)正在阻塞(阻止任何其他任务被调度)。一旦我们调用await,我们就明确地通知调度程序我们正在等待某事(通常是 I/O,但这里只是“睡眠”)。类似地,在它调用之前f(1)阻止f(2)出去await。
如果我们删除阻塞部分(阻塞 0s)f(1)将被重新安排到执行之前f(2),因此将首先完成:
>>> start = datetime.now()
>>> asyncio.create_task(f(2, block_for=0))
>>> asyncio.create_task(f(1, block_for=0))
2 IN 0s
2 AWAIT 0s
1 IN 0s
1 AWAIT 0s
1 OUT 1s
2 OUT 2s
最后,关于这部分:
......如何安排它在未来被调用?
你可以看看python中的asyncio.sleep()是怎么实现的?,它可能会帮助您更好地理解异步编程的工作原理。
添加回答
举报