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()是怎么實現的?,它可能會幫助您更好地理解異步編程的工作原理。
添加回答
舉報