4.1 方法 run()
模組 asyncio 提供了多種方法和函數來創建和管理非同步程式。以下是一些最受歡迎和常用的asyncio方法和函數。
今天我們將討論最常見的4種:
run()sleep()wait()gather()
接下來是詳細介紹:
方法 asyncio.run(coroutine)
這個方法用來啟動非同步程序。當你需要從同步上下文(例如程式主線程)中執行非同步代碼時,特別有用。
方法 asyncio.run() 啟動主協程並管理事件循環的創建和關閉。這個方法自動創建新的事件循環,並在協程完成時終止它。
用法:
asyncio.run(async_function(), *, debug=False)
-
async_function: 要執行的協程。 -
debug: 可選參數,為事件循環啟用調試模式。
使用範例:
import asyncio
async def main():
print('Hello')
await asyncio.sleep(1)
print('World')
asyncio.run(main())
限制
不能從其他事件循環內部呼叫:
asyncio.run() 僅能從同步代碼呼叫,因為它創建和終止其自己的事件循環。如果嘗試從已存在的事件循環內部調用此方法,將引發錯誤。
僅適用於頂層:
此方法旨在啟動程式的主入口,且不應用於嵌套的非同步函數調用。
4.2 方法 sleep()
當你需要將協程停止一段時間,但不想阻塞其他協程的執行時,這個方法非常有用。
方法 asyncio.sleep() 在 asyncio 模組中用於將當前協程暫停指定的秒數。
這個方法不同於time.sleep(),因為它允許其他任務在暫停期間執行。這使得它對需要不阻塞主線程的延遲或等待的非同步程式編寫很有用。
用法:
asyncio.sleep(delay, result=None)
-
delay: 延遲時間(以秒計,可以是小數)。 -
result: 可選結果,將在延遲結束後返回。
應用範例:
import asyncio
async def main():
print('Start sleeping')
await asyncio.sleep(2)
print('Wake up')
asyncio.run(main())
在這個範例中,協程 main 暫停了2秒,使其他任務在這段時間內執行,然後繼續並打印 "Wake up"。
4.3 方法 wait()
當你需要等待多個非同步操作完成,但希望對等待過程有更細的控制時,這個方法非常有用。
方法 asyncio.wait() 在 asyncio 模組中允許等待多個非同步任務或協程的完成。可以等待所有任務完成、第一個完成的任務或任何任務出錯。
與 gather() 不同,wait() 方法提供對等待過程的更大控制,允許設置timeout和完成條件。
方法 asyncio.wait() 的主要特徵
用法:
asyncio.wait(fs, *, timeout=None, return_when=ALL_COMPLETED)
其中:
-
fs: 需要等待的Future對象或協程的集合。 -
timeout: 可選參數,指定最大等待時間(以秒計)。如果等待時間超時,則返回那些在此期間完成的任務。 -
return_when: 指定方法應結束的條件。可能的值:-
ALL_COMPLETED: 當所有任務完成時返回結果(默認)。 -
FIRST_COMPLETED: 當第一個任務完成時返回結果。 -
FIRST_EXCEPTION: 當任何任務出錯時返回結果。
-
等待多個任務或協程完成。可以指定等待時間和完成條件。
import asyncio
async def say(what, delay):
await asyncio.sleep(delay)
return what
async def main():
task1 = asyncio.create_task(say('hello', 1))
task2 = asyncio.create_task(say('world', 2))
done, pending = await asyncio.wait([task1, task2], timeout=1.5)
for task in done:
print(task.result())
asyncio.run(main())
在上面的範例中,我們使用 create_task() 方法將每個協程 say() 包裝在 Task 對象中,然後將這些任務的列表傳遞給 wait() 方法。Task 對象允許協程並行執行,而不必等待一個完成後再啟動另一個。
wait 方法將等待任務執行1.5秒,然後返回元組的任務:第一個值包含已完成的任務 (done),第二個是仍在進行中的任務 (pending)。
4.4 方法 gather()
當你需要並行啟動多個非同步操作並將它們的結果以列表形式獲取時,這個方法特別有用。
方法 asyncio.gather() 在 asyncio 模組中用於並行執行多個非同步任務並以列表形式返回它們的結果。這是一種方便的方式來分組協程或任務並等待它們的完成。
方法 asyncio.gather() 的主要特徵
用法:
asyncio.gather(*coros_or_futures, return_exceptions=False)
其中:
-
coros_or_futures: 要執行的協程或Future對象。 -
return_exceptions: 布林值,指示是否應將異常作為結果返回。默認為False。
使用範例
import asyncio
async def say_after(delay, what):
await asyncio.sleep(delay)
return what
async def main():
results = await asyncio.gather(
say_after(1, 'hello'),
say_after(2, 'world')
)
print(results)
asyncio.run(main())
此範例展示了如何使用 asyncio.gather 來並行執行多個任務,每個任務都有其自己的延遲時間。所有任務的結果以列表形式返回。與 wait 不同的是,gather 不僅等待任務完成,還收集所有協程的結果,這使得它在每個任務的結果很重要時非常方便。
GO TO FULL VERSION