成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python異步與 JavaScript 原生異步有什么區別?

開發 后端
眾所周知,JavaScript 是單線程的,所以瀏覽器通過 JavaScript 發起的請求是異步請求。Python 自帶的 asyncio 模塊為 Python 帶來了原生的異步能力。

 眾所周知,JavaScript 是單線程的,所以瀏覽器通過 JavaScript 發起的請求是異步請求。Python 自帶的 asyncio 模塊為 Python 帶來了原生的異步能力。

[[319529]]

在學習 asyncio 時,我們應當正確認識到異步代碼在 Python 中與 JavaScript 原生代碼中有什么區別,這樣才能更好地理解Python中用同步代碼寫異步程序這個邏輯。

對于異步操作,我們如果使用日常生活中的例子,可能會幫助我們理解 JavaScript 原生的異步操作,但是卻有可能阻礙我們理解 Python 的異步操作。

例如:我把洗衣機打開,等待洗衣機自動運行的這段時間,我可以去煮飯,等待飯煮好的這個過程,我可以去看書。

現在假設我們要請求一個網址:http://httpbin.org/delay/5,這個網址請求以后,需要等待5秒鐘才會返回結果。我們使用 jQuery來寫一段 JavaScript 代碼:

 

  1. function test_async(){ 
  2.     $.ajax({type: 'GET'
  3.             contentType: 'application/json; charset=utf-8'
  4.             url: 'http://httpbin.org/delay/5'
  5.             success: function (response) { 
  6.                 console.log('5秒請求返回:', response) 
  7.  
  8.             } 
  9.         }) 
  10.     var a = 1 + 1 
  11.     a = a * 2 
  12.     console.log(a) 
  13.     $.ajax({type: 'GET'
  14.             contentType: 'application/json; charset=utf-8'
  15.             url: 'http://httpbin.org/ip'
  16.             success: function (response) { 
  17.                 console.log('查詢 IP 返回:', response) 
  18.  
  19.             } 
  20.         }) 
  21.     console.log('這里是代碼的末尾'

運行效果如下圖所示:

 

可以看出來,整個代碼的執行邏輯與我們生活中的異步是一致的,首先發起了一個5秒的請求,但是程序不會卡住等待,而是繼續運行后面的代碼,然后發起新的請求。由于新的請求返回時間短,所以新的請求很快返回并打印,最后才是打印的5秒請求的返回結果。

這就像是我們打開了洗衣機的電源,然后去淘米煮飯,米放進了電飯鍋,打開電飯鍋電源,然后去看書,最后飯先煮好,然后衣服再洗完。

JavaScript 原生的異步請求的過程,與日常生活中的邏輯很像。所以很容易就能理解 JavaScript 的異步流程。

但是 Python 里面,異步又是另外一種情況了。

我們來寫一段代碼:

 

  1. import asyncio 
  2. import aiohttp 
  3.  
  4. async def main(): 
  5.     async with aiohttp.ClientSession() as client: 
  6.         response = await client.get('http://httpbin.org/delay/5'
  7.         result = await response.json() 
  8.         print('5秒請求返回:', result) 
  9.         a = 1 + 1 
  10.         a = a * 2 
  11.         print(a) 
  12.         new_response = await client.get('http://httpbin.org/ip'
  13.         new_result = await new_response.json() 
  14.         print('查詢 IP 返回:', new_result) 
  15.         print('這里是代碼的末尾'
  16.  
  17. asyncio.run(main()) 

運行效果如下圖所示:

 

可以看出,程序依然是串行運行的,根本就沒有異步痕跡。

要讓程序異步運行,我們需要湊夠一批任務提交給 asyncio,讓它自己通過事件循環來調度這些任務:

 

  1. import asyncio 
  2. import aiohttp 
  3.  
  4.  
  5. async def do_plus(): 
  6.     a = 1 + 1 
  7.     a = a * 2 
  8.     print(a) 
  9.  
  10.  
  11. async def test_delay(client): 
  12.     response = await client.get('http://httpbin.org/delay/5'
  13.     result = await response.json() 
  14.     print('5秒請求返回:', result) 
  15.  
  16.  
  17. async def test_ip(client): 
  18.     response = await client.get('http://httpbin.org/ip'
  19.     result = await response.json() 
  20.     print('查詢 IP 返回:', result) 
  21.  
  22.  
  23. async def test_print(): 
  24.     print('這里是代碼的末尾'
  25.  
  26.  
  27. async def main(): 
  28.     async with aiohttp.ClientSession() as client: 
  29.         tasks = [ 
  30.                 asyncio.create_task(test_delay(client)), 
  31.                 asyncio.create_task(do_plus()), 
  32.                 asyncio.create_task(test_ip(client)), 
  33.                 asyncio.create_task(test_print()) 
  34.                 ] 
  35.         await asyncio.gather(*tasks) 
  36.  
  37. asyncio.run(main()) 

運行效果如下圖所示:

 

 

 

 

這是由于,在asyncio 里面,task是可以并行的最小單位,并且,task 要湊夠一批一起通過asyncio.gather或者asyncio.wait提交給事件循環以后,才能并行起來。

當使用代碼asyncio.create_task(異步函數())的時候,這個異步函數實際上并沒有真正運行,所以,在上面的代碼中:

 

  1. tasks = [ 
  2.                 asyncio.create_task(test_delay(client)), 
  3.                 asyncio.create_task(do_plus()), 
  4.                 asyncio.create_task(test_ip(client)), 
  5.                 asyncio.create_task(test_print()) 
  6.                 ] 

創建了一個包含4個task 的列表,此時這4個異步函數中的代碼都還沒有執行。

當再調用await asyncio.gather(*tasks)時,這4個任務被作為4個參數傳入到了 asyncio.gather函數中,于是 Python 的事件循環開始調度他們。在這些異步函數中,包含await的地方,就是在告訴 Python,await后面的這個函數可能會有 IO 等待,可以掛起等一會再來看,現在可以去檢查事件循環里面其他異步任務是否已經結束等待可以運行。而沒有 await的地方依然是串行的,例如do_plus里面的三行代碼就是按順序一次性運行完成的。

所以,當我們使用 Python 的 asyncio 寫異步代碼時,我們需要提前安排好異步的切換位置并包裝為異步任務,然后把一批任務一次性提交給 asyncio,讓 Python 自己根據我們安排好的切換邏輯來調度這些任務。

這就像是,當我寫 JavaScript 的時候,我親自上陣先把洗衣機電源打開,然后我再來考慮接下來要利用等待時間做什么事情。

當我寫 Python 的時候,我需要提前把整個計劃都安排好:先打開洗衣機,在等待的時間淘米煮飯,然后再看書。并把這個計劃表提交給一個專門做事情的人來執行。

理解了這個差別,才能更好地在 Python 中使用 asyncio。

注意,本文說到的 JavaScript異步,是 JavaScript 最原始的異步邏輯。現在 JavaScript 有 Promise 等等高級功能,實現類似于 Python 的這種異步邏輯。

責任編輯:華軒 來源: 未聞Code
相關推薦

2017-07-13 12:12:19

前端JavaScript異步編程

2020-12-22 13:46:48

APISKD

2011-08-08 14:09:55

dhcpbootp

2018-07-13 17:05:22

SQLMySQL數據庫

2023-10-13 15:48:17

OT系統

2011-11-11 15:47:22

JavaScript

2017-05-11 20:20:59

JavascriptPromiseWeb

2020-09-25 18:10:06

Python 開發編程語言

2020-09-06 09:51:57

SNMP TrapSyslog網絡協議

2019-02-27 15:22:15

混合云云計算多云

2021-05-16 15:28:59

沙箱容器惡意軟件

2021-03-13 17:48:07

JavaScriptObject.is()運算符

2020-10-15 13:29:57

javascript

2020-11-14 15:38:38

JavaScript代碼技術

2020-08-02 23:20:36

JavaScriptmap()forEach()

2024-06-24 21:24:12

云計算云網絡

2022-09-14 09:45:15

指標標簽

2012-07-25 15:45:28

ERPSCM

2022-11-22 10:21:23

5GLTE

2024-02-21 14:37:56

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品二区亚洲w码 | 日韩精品视频在线免费观看 | 国产精品极品美女在线观看免费 | 国产精品一区在线观看 | 国产精品99一区二区 | 99精品视频免费观看 | 亚洲精品久久久久中文字幕欢迎你 | 不卡视频一区二区三区 | 亚洲午夜电影 | 国产在线播 | 欧美一区免费在线观看 | av黄色在线观看 | 在线视频一区二区 | 国产 亚洲 网红 主播 | 在线观看中文字幕视频 | 欧美一级片免费看 | 亚洲欧美另类在线 | 亚洲欧美中文日韩在线v日本 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 涩涩视频网 | 午夜伦理影院 | 久久爱一区| 久久99精品久久久久子伦 | 日韩欧美在线视频一区 | 久久精品久久久 | 亚洲欧美日韩精品久久亚洲区 | 国产四区| 91极品视频 | 日批av| 国产精品99久久久久久宅男 | 国产精品资源在线 | 成人在线播放网址 | 久久精品一区 | 欧美一区二区三区视频 | 婷婷在线网站 | 久久久久久网 | 久久久激情 | 五月婷婷色 | 欧产日产国产精品视频 | 日本一区二区三区免费观看 | 久热精品视频 |