async 和 await 入門知識點總結

2021-10-04 17:19:02 字數 2738 閱讀 4217

參考:

謝謝博主大大!

1."普通函式", 現在我們用 async 把它們公升級為 "非同步函式".

一、首先要知道什麼是協程、非同步。

舉個例子:假設有1個洗衣房,裡面有10臺洗衣機,有乙個洗衣工在負責這10臺洗衣機。那麼洗衣房就相當於1個程序,洗衣工就相當1個執行緒。如果有10個洗衣工,就相當於10個執行緒,1個程序是可以開多執行緒的。這就是多執行緒!

那麼協程呢?先不急。大家都知道,洗衣機洗衣服是需要等待時間的,如果10個洗衣工,1人負責1臺洗衣機,這樣效率肯定會提高,但是不覺得浪費資源嗎?明明1 個人能做的事,卻要10個人來做。只是把衣服放進去,開啟開關,就沒事做了,等衣服洗好再拿出來就可以了。就算很多人來洗衣服,1個人也足以應付了,開好第一台洗衣機,在等待的時候去開第二台洗衣機,再開第三台,……直到有衣服洗好了,就回來把衣服取出來,接著再取另一台的(哪台洗好先就取哪台,所以協程是無序的)。這就是計算機的協程!洗衣機就是執行的方法。

當你程式中方法需要等待時間的話,就可以用協程,效率高,消耗資源少。

注: 乙個非同步的函式, 有個更標準的稱呼, 我們叫它 "協程" (coroutine).
第乙個問題是, await 後面必須跟乙個 awaitable 型別或者具有await屬性的

物件. 這個 awaitable, 並不是我們認為 sleep() 是 awaitable 就可以 await 了,

常見的 awaitable 物件應該是:

await asyncio.sleep(3) # asyncio 庫的 sleep() 機制與 time.sleep() 不

# 同, 前者是 "假性睡眠", 後者是會導致執行緒阻塞的 "真性睡眠"

await an_async_function() # 乙個非同步的函式, 也是可等待的物件

def demo4():

"""這是最終我們想要的實現.

"""import asyncio # 引入 asyncio 庫

async def washing1():

await asyncio.sleep(3) # 使用 asyncio.sleep(), 它返回的是乙個可等待的物件

print('washer1 finished')

async def washing2():

await asyncio.sleep(2)

print('washer2 finished')

async def washing3():

await asyncio.sleep(5)

print('washer3 finished')

"""事件迴圈機制分為以下幾步驟:

1. 建立乙個事件迴圈

2. 將非同步函式加入事件佇列

3. 執行事件佇列, 直到最晚的乙個事件被處理完畢後結束

4. 最後建議用 close() 方法關閉事件迴圈, 以徹底清理 loop 物件防止誤用

"""# 1. 建立乙個事件迴圈

loop = asyncio.get_event_loop()

# 2. 將非同步函式加入事件佇列

tasks = [

washing1(),

washing2(),

washing3(),

]# 3. 執行事件佇列, 直到最晚的乙個事件被處理完畢後結束

loop.run_until_complete(asyncio.wait(tasks))

"""ps: 如果不滿意想要 "多洗幾遍", 可以多寫幾句:

loop.run_until_complete(asyncio.wait(tasks))

loop.run_until_complete(asyncio.wait(tasks))

loop.run_until_complete(asyncio.wait(tasks))

..."""

# 4. 如果不再使用 loop, 建議養成良好關閉的習慣

# (有點類似於檔案讀寫結束時的 close() 操作)

loop.close()

"""最終的列印效果:

washer2 finished

washer1 finished

washer3 finished

elapsed time = 5.126561641693115

(畢竟切換執行緒也要有點耗時的)

說句題外話, 我看有的博主的加入事件佇列是這樣寫的:

tasks = [

loop.create_task(washing1()),

loop.create_task(washing2()),

loop.create_task(washing3()),

]執行的效果是一樣的, 暫不清楚為什麼他們這樣做.

"""if __name__ == '__main__':

# 為驗證是否真的縮短了時間, 我們計個時

start = time()

# demo1() # 需花費10秒

# demo2() # 會報錯: runtimewarning: coroutine ... was never awaited

# demo3() # 會報錯: runtimewarning: coroutine ... was never awaited

demo4() # 需花費5秒多一點點

end = time()

print('elapsed time = ' + str(end - start))

async和await的講解

普通的函式宣告 async function a 複製 宣告乙個函式表示式 let a async function 複製 async形式的箭頭函式 let a async 複製 async與await例項應用,基礎 控制器呼叫與server中查詢資料 exports.getbloglist asy...

async和await的使用

async其實是es7的才有的,是非同步操作的進化,其實就是封裝乙個promise的物件返回 async function test console.log test promiseasync方法在普通的函式前加上 async 關鍵字即可。執行這個函式,發現並沒有返回1111,而是通過promise...

async和await的講解

async和await的講解 宣告async函式的幾個方法 普通的函式宣告 async function a 宣告乙個函式表示式 let a async function async形式的箭頭函式 let a async 初識async和await async與await例項應用,基礎 控制器呼叫與...