async/await關鍵字是出如今python3.4之後。網上已經有不少文章對async/await這兩個關鍵字都有講解,包括如何由python2的yield from發展到async/await這兩個關鍵字,以及一些代碼實現都有。可是對於像我這樣初次接觸的人來講,光看代碼分析也不必定能理解,我也是在度娘上搜索不少相關的網站,當中也有官網,都沒有發現能讓我一眼看懂在什麼地方能夠用await,什麼狀況用await的文章。通過本身的從新思考,總算對async、await有一些初步的瞭解,因此想把本身的理解記錄下來,但願對一些學習協程或者異步的初學者也有必定的幫助。python
對於網上能搜到的一些代碼實現、例子,這裏就不重複了。segmentfault
1、首先要知道什麼是協程、異步。多線程
舉個例子:假設有1個洗衣房,裏面有10臺洗衣機,有一個洗衣工在負責這10臺洗衣機。那麼洗衣房就至關於1個進程,洗衣工就至關1個線程。若是有10個洗衣工,就至關於10個線程,1個進程是能夠開多線程的。這就是多線程!app
那麼協程呢?先不急。你們都知道,洗衣機洗衣服是須要等待時間的,若是10個洗衣工,1人負責1臺洗衣機,這樣效率確定會提升,可是不以爲浪費資源嗎?明明1 我的能作的事,卻要10我的來作。只是把衣服放進去,打開開關,就沒事作了,等衣服洗好再拿出來就能夠了。就算不少人來洗衣服,1我的也足以應付了,開好第一臺洗衣機,在等待的時候去開第二臺洗衣機,再開第三臺,……直到有衣服洗好了,就回來把衣服取出來,接着再取另外一臺的(哪臺洗好先就取哪臺,因此協程是無序的)。這就是計算機的協程!洗衣機就是執行的方法。異步
當你程序中方法須要等待時間的話,就能夠用協程,效率高,消耗資源少。async
好了!如今來總結一下:函數
洗衣房 ==> 進程oop
洗衣工 ==> 線程學習
洗衣機 ==> 方法(函數)網站
2、async\await 的使用
正常的函數在執行時是不會中斷的,因此你要寫一個可以中斷的函數,就須要添加async關鍵。
async 用來聲明一個函數爲異步函數,異步函數的特色是能在函數執行過程當中掛起,去執行其餘異步函數,等到掛起條件(假設掛起條件是sleep(5))消失後,也就是5秒到了再回來執行。
await 用來用來聲明程序掛起,好比異步程序執行到某一步時須要等待的時間很長,就將此掛起,去執行其餘的異步程序。await 後面只能跟異步程序或有__await__屬性的對象,由於異步程序與通常程序不一樣。假設有兩個異步函數async a,async b,a中的某一步有await,當程序碰到關鍵字await b()後,異步程序掛起後去執行另外一個異步b程序,就是從函數內部跳出去執行其餘函數,當掛起條件消失後,無論b是否執行完,要立刻從b程序中跳出來,回到原程序執行原來的操做。若是await後面跟的b函數不是異步函數,那麼操做就只能等b執行完再返回,沒法在b執行的過程當中返回。若是要在b執行完才返回,也就不須要用await關鍵字了,直接調用b函數就行。因此這就須要await後面跟的是異步函數了。在一個異步函數中,能夠不止一次掛起,也就是能夠用多個await。
3、實例:
1 async def test2(i): 2 r = await other_test(i) 3 print(i,r) 4 5 async def other_test(i): 6 r = requests.get(i) 7 print(i) 8 await asyncio.sleep(4) 9 print(time.time()-start) 10 return r 11 12 url = ["https://segmentfault.com/p/1210000013564725", 13 "https://www.jianshu.com/p/83badc8028bd", 14 "https://www.baidu.com/"] 15 16 loop = asyncio.get_event_loop() 17 task = [asyncio.ensure_future(test2(i)) for i in url] 18 start = time.time() 19 20 loop.run_until_complete(asyncio.wait(task)) 21 endtime = time.time()-start 22 print(endtime) 23 loop.close()
輸出結果:
1 https://segmentfault.com/p/1210000013564725 2 https://www.jianshu.com/p/83badc8028bd 3 https://www.baidu.com/ 4 4.425147771835327 5 https://segmentfault.com/p/1210000013564725 <Response [200]> 6 4.5975635051727295 7 https://www.jianshu.com/p/83badc8028bd <Response [403]> 8 4.722797632217407 9 https://www.baidu.com/ <Response [200]> 10 4.722797632217407
對於下面這幾行代碼:
loop = asyncio.get_event_loop() task = [asyncio.ensure_future(test2(i)) for i in url] loop.run_until_complete(asyncio.wait(task)) loop.close()
能夠在網上找到具體講解,在這可用下圖來粗略形容一下

當全部的異步程序運行完就會返回最後結果。
對於什麼是task和future,asyncio.wait()與asyncio.gather()、asyncio.ensure_future()這些你們能夠網上找到解釋。
說到這裏,相信你也大概清楚在何時用async、何時await了吧! 若是有說得不對的地方,請多多指正!!