簡體   English   中英

從異步 function 調用普通 function 與從異步 function 等待協程有什么區別?

[英]what's the difference of calling a normal function from async function with await a coroutine from an async function?

  1.  async def caller(): await bar() print("finish") async def bar(): // some code here
  2.  async def caller(): bar() print("finish") def bar(): //some code here

在上面的例子中。 對於這兩種情況,調用者都必須等待 bar() 完成。 對於這種情況, bar 是普通/協程有什么區別嗎? 如果我們想“等待”一些功能,為什么不直接使用普通的 function。

不同之處在於,在第二個示例中, bar()是一個非異步 function,因此它本身不能等待任何東西。 例如,如果您想從bar()中訪問 web 服務,那么在第一個示例中不會有問題,您只需使用aiohttp 即可 在第二個示例中,這幾乎是不可能的,因為異步庫需要從異步函數中使用,而非異步庫將在等待響應時阻塞整個事件循環。

如果我們想“等待”一些功能,為什么不直接使用普通的 function。

如果您等待的 function 不需要與外界通信(例如,如果它只是在 dict 中打亂數據),它可以而且應該是一個正常的 function。另一方面,如果它需要做 IO,它應該是一個異步 function。

如果它不是async function,那么您顯然不需要await它。 並非您在async function 中調用的每個 function 都必須是async的,也不必await 您可以從async function 中調用常規的非異步函數。

整個 asyncio model 圍繞一個事件循環工作。 任何時候只能運行一個任務,事件循環協調當前正在運行的任務。 function 中的await暫停 function 的執行,並允許在事件循環中運行另一個任務。 所以,在這個例子中:

async def caller():
    await bar()
    print('finish')

執行過程是這樣的:

  1. caller()在事件循環中被調用和調度,一旦可用,它將立即執行。
  2. 它調用bar() ,后者安排在事件循環中執行。
  3. await暫停caller的執行。
  4. 事件循環執行bar 假設它正在發出一個.network 請求,所以在該響應返回之前什么都不會發生,事件循環可以自由運行任何其他計划的異步任務......
  5. .network 響應返回,事件循環恢復bar的執行。
  6. bar結束,事件循環恢復caller的執行。

await的存在是為了協調異步任務運行的順序,以及什么任務取決於什么其他任務的結果。

  1.  async def caller(): await bar() print("finish") async def bar(): // some code here
  2.  async def caller(): bar() print("finish") def bar(): //some code here

在上面的例子中。 對於這兩種情況,調用者都必須等待 bar() 的完成。 bar 在這種情況下成為正常/協程有什么區別? 如果我們想“等待”某些功能,為什么不直接使用普通的 function。

協程不能在簡單的調用中運行,它需要在事件循環中運行。 事件循環將監聽我們添加到事件池中的事件並在事件觸發時執行回調 當它執行代碼的“等待”部分時,這可能意味着有一些 I/O 邊界任務,所以事件循環將在下一個事件發生時為 go,這樣就不會阻塞線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM