国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

淺談JavaScript中的異步處理

開發 后端
在 JavaScript 的世界中,所有代碼都是單線程執行的,由于這個“缺陷”,導致 JavaScript 的所有網絡操作,瀏覽器事件,都必須是異步執行。主流的異步處理方案主要有:回調函數 (CallBack) 、 Promise 、 Generator 函數、 async/await 。

在 JavaScript 的世界中,所有代碼都是單線程執行的,由于這個“缺陷”,導致 JavaScript 的所有網絡操作,瀏覽器事件,都必須是異步執行。

異步執行可以用回調函數實現。

異步操作會在將來的某個時間點觸發一個函數調用。

主流的異步處理方案主要有:回調函數 (CallBack) 、 Promise 、 Generator 函數、 async/await 。

[[201412]]

一、回調函數(CallBack)

這是異步編程最基本的方法

假設我們有一個 getData 方法,用于異步獲取數據,***個參數為請求的 url 地址,第二個參數是回調函數,如下:

 

  1. function getData(url, callBack){ 
  2.     // 模擬發送網絡請求 
  3.     setTimeout(()=> { 
  4.         // 假設 res 就是返回的數據 
  5.         var res = { 
  6.             url: url, 
  7.             data: Math.random() 
  8.         } 
  9.         // 執行回調,將數據作為參數傳遞 
  10.         callBack(res) 
  11.     }, 1000) 

我們預先設定一個場景,假設我們要請求三次服務器,每一次的請求依賴上一次請求的結果,如下:

 

  1. getData('/page/1?param=123', (res1) => { 
  2.     console.log(res1) 
  3.     getData(`/page/2?param=${res1.data}`, (res2) => { 
  4.         console.log(res2) 
  5.         getData(`/page/3?param=${res2.data}`, (res3) => { 
  6.             console.log(res3) 
  7.         }) 
  8.     }) 
  9. }) 
  • 通過上面的代碼可以看出,***次請求的 url 地址為: /page/1?param=123 ,返回結果為 res1 。
  • 第二個請求的 url 地址為: /page/2?param=${res1.data} ,依賴***次請求的 res1.data ,返回結果為 res2`。
  • 第三次請求的 url 地址為: /page/3?param=${res2.data} ,依賴第二次請求的 res2.data ,返回結果為 res3 。

由于后續請求依賴前一個請求的結果,所以我們只能把下一次請求寫到上一次請求的回調函數內部,這樣就形成了常說的:回調地獄。

二、發布/訂閱

我們假定,存在一個”信號中心”,某個任務執行完成,就向信號中心”發布”( publish )一個信號,其他任務可以向信號中心”訂閱”( subscribe )這個信號,從而知道什么時候自己可以開始執行。這就叫做”發布/訂閱模式”(publish-subscribe pattern),又稱”觀察者模式”(observer pattern)

這個模式有多種實現,下面采用的是Ben Alman的 Tiny Pub/Sub ,這是 jQuery 的一個插件

首先, f2 向”信號中心” jQuery 訂閱” done “信號

  1. jQuery.subscribe("done", f2); 

f1進行如下改寫

 

  1. function f1(){ 
  2.     setTimeout(function(){ 
  3.       // f1的任務代碼 
  4.       jQuery.publish("done"); 
  5.     }, 1000); 

jQuery.publish("done") 的意思是, f1 執行完成后,向”信號中心 "jQuery 發布 "done" 信號,從而引發f2的執行。 此外,f2完成執行后,也可以取消訂閱( unsubscribe )

  1. jQuery.unsubscribe("done", f2); 

這種方法的性質與”事件監聽”類似,但是明顯優于后者。因為我們可以通過查看”消息中心”,了解存在多少信號、每個信號有多少訂閱者,從而監控程序的運行。

三、Promise

Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大

所謂 Promise ,簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說, Promise 是一個對象,從它可以獲取異步操作的消息。 Promise 提供統一的 API ,各種異步操作都可以用同樣的方法進行處理

簡單說,它的思想是,每一個異步任務返回一個 Promise 對象,該對象有一個 then 方法,允許指定回調函數。

現在我們使用 Promise 重新實現上面的案例,首先,我們要把異步請求數據的方法封裝成 Promise

 

  1. function getDataAsync(url){ 
  2.     return new Promise((resolve, reject) => { 
  3.         setTimeout(()=> { 
  4.             var res = { 
  5.                 url: url, 
  6.                 data: Math.random() 
  7.             } 
  8.             resolve(res) 
  9.         }, 1000) 
  10.     }) 

那么請求的代碼應該這樣寫

 

  1. getDataAsync('/page/1?param=123'
  2.     .then(res1=> { 
  3.         console.log(res1) 
  4.         return getDataAsync(`/page/2?param=${res1.data}`) 
  5.     }) 
  6.     .then(res2=> { 
  7.         console.log(res2) 
  8.         return getDataAsync(`/page/3?param=${res2.data}`) 
  9.     }) 
  10.     .then(res3=> { 
  11.         console.log(res3) 
  12.     }) 

then 方法返回一個新的 Promise 對象, then 方法的鏈式調用避免了 CallBack 回調地獄

但也并不是***,比如我們要添加很多 then 語句, 每一個 then 還是要寫一個回調。

如果場景再復雜一點,比如后邊的每一個請求依賴前面所有請求的結果,而不僅僅依賴上一次請求的結果,那會更復雜。 為了做的更好, async/await 就應運而生了,來看看使用 async/await 要如何實現

四、async/await

getDataAsync 方法不變,如下

 

  1.  function getDataAsync(url){ 
  2.     return new Promise((resolve, reject) => { 
  3.         setTimeout(()=> { 
  4.             var res = { 
  5.                 url: url, 
  6.                 data: Math.random() 
  7.             } 
  8.             resolve(res) 
  9.         }, 1000) 
  10.     }) 

業務代碼如下

 

  1. async function getData(){ 
  2.     var res1 = await getDataAsync('/page/1?param=123'
  3.     console.log(res1) 
  4.     var res2 = await getDataAsync(`/page/2?param=${res1.data}`) 
  5.     console.log(res2) 
  6.     var res3 = await getDataAsync(`/page/2?param=${res2.data}`) 
  7.     console.log(res3) 

可以看到使用 async\await 就像寫同步代碼一樣

對比 Promise 感覺怎么樣?是不是非常清晰,但是 async/await 是基于 Promise 的,因為使用 async 修飾的方法最終返回一個 Promise , 實際上, async/await 可以看做是使用 Generator 函數處理異步的語法糖,我們來看看如何使用 Generator 函數處理異步

五、Generator

首先異步函數依然是

 

  1. function getDataAsync(url){ 
  2.     return new Promise((resolve, reject) => { 
  3.         setTimeout(()=> { 
  4.             var res = { 
  5.                 url: url, 
  6.                 data: Math.random() 
  7.             } 
  8.             resolve(res) 
  9.         }, 1000) 
  10.     }) 

使用 Generator 函數可以這樣寫

 

  1. function*getData(){ 
  2.     var res1 = yield getDataAsync('/page/1?param=123'
  3.     console.log(res1) 
  4.     var res2 = yield getDataAsync(`/page/2?param=${res1.data}`) 
  5.     console.log(res2) 
  6.     var res3 = yield getDataAsync(`/page/2?param=${res2.data}`) 
  7.     console.log(res3)) 

然后我們這樣逐步執行

 

  1. var g = getData() 
  2. g.next().value.then(res1=> { 
  3.     g.next(res1).value.then(res2=> { 
  4.         g.next(res2).value.then(()=> { 
  5.             g.next() 
  6.         }) 
  7.     }) 
  8. }) 

上面的代碼,我們逐步調用遍歷器的 next() 方法,由于每一個 next() 方法返回值的 value 屬性為一個 Promise 對象

所以我們為其添加 then 方法, 在 then 方法里面接著運行 next 方法挪移遍歷器指針,直到 Generator 函數運行完成,實際上,這個過程我們不必手動完成,可以封裝成一個簡單的執行器

 

  1. function run(gen){ 
  2.     var g = gen() 
  3.  
  4.     function next(data){ 
  5.         var res = g.next(data) 
  6.         if (res.done) return res.value 
  7.         res.value.then((data) => { 
  8.             next(data) 
  9.         }) 
  10.     } 
  11.  
  12.     next() 
  13.  

run 方法用來自動運行異步的 Generator 函數,其實就是一個遞歸的過程調用的過程。這樣我們就不必手動執行 Generator 函數了。 有了 run 方法,我們只需要這樣運行 getData 方法

  1. run(getData) 

這樣,我們就可以把異步操作封裝到 Generator 函數內部,使用 run 方法作為 Generator 函數的自執行器,來處理異步。其實我們不難發現, async/await 方法相比于 Generator 處理異步的方式,有很多相似的地方,只不過 async/await 在語義化方面更加明顯,同時 async/await 不需要我們手寫執行器,其內部已經幫我們封裝好了,這就是為什么說 async/await 是 Generator 函數處理異步的語法糖了。

責任編輯:未麗燕 來源: Poetry's Blog
相關推薦

2020-04-07 00:10:16

javascrip語言異步

2009-03-11 15:30:05

evalwithJavascript

2017-08-22 16:40:22

前端JavaScript接口

2023-11-29 07:38:33

JavaScript異步處理

2009-06-10 22:06:29

JavaScript面向對象

2013-12-25 10:08:42

ember.js異步處理

2014-06-05 09:29:03

數據處理

2011-07-05 10:20:38

java

2013-03-26 10:27:01

JavaScriptjson

2011-07-14 10:58:26

JavaScript強制類型轉換函數

2009-06-18 12:21:07

javascriptdom

2009-04-21 09:37:50

ASP.NETAjaxJavaScript

2009-06-24 10:49:16

JavaScript

2015-05-06 10:02:26

2020-10-15 13:29:57

javascript

2010-10-08 10:03:52

JavaScript圖像

2010-12-01 14:34:59

AsyncTask異步處理任務Android

2009-08-21 11:02:55

C#異步調用

2018-11-08 15:30:04

JavaScriptES6異步

2021-12-10 07:47:30

Javascript異步編程
點贊
收藏

51CTO技術棧公眾號

涩爱av色老久久精品偷偷鲁| 日韩欧美一区二区三区免费观看| 亚洲老妇激情| 制服丝袜av成人在线看| 99在线免费观看| 六月丁香综合在线视频| 日本欧美中文字幕| 国产黄大片在线观看| 色综合色综合色综合色综合色综合 | 佐山爱痴汉视频一区二区三区 | 制服.丝袜.亚洲.另类.中文| www99xav| 久久香蕉国产线看观看99| 特级西西人体www高清大胆| 免费视频一区| 精品一区2区三区| 综合久久99| 国产精品日韩一区二区三区| 欧美精品亚洲精品| 中文字幕日韩一区二区不卡 | 中文字幕中文字幕在线中一区高清| 成人中文在线| 国产人妖伪娘一区91| 天堂av一区| 日本欧美视频| 国产不卡在线播放| 欧美理论片在线观看| 精品无人乱码一区二区三区| 亚洲精品一区二区三区福利| 操你啦视频在线| 欧美一级欧美三级在线观看| 欧美人与性动交α欧美精品济南到 | 国产精品久久..4399| 免费成人在线视频观看| 四虎一区二区| www.日本不卡| 国产乱xxⅹxx国语对白| 欧美视频中文在线看| 在线成人福利| 国产视频精品免费播放| 亚洲国产精选| 国产精品视频自拍| 日韩综合一区二区| 18禁网站免费无遮挡无码中文| 国产三区在线成人av| 免费在线视频你懂得| 日韩欧美国产一二三区| 国产午夜精品一区在线观看| 91丝袜美腿美女视频网站| 麻豆视频一区二区| 日本五十路在线| 日韩免费观看高清完整版| www一区二区三区| 69堂成人精品视频免费| 啊啊啊射了视频网站| 在线日韩av片| 国产91亚洲精品久久久| av免费观看久久| 久久伊人中文字幕| 国产天堂在线播放视频| 国产精品欧美一区二区| 国产成人免费视| chinese偷拍一区二区三区| 97视频免费在线观看| 国产一区二区调教| 在线视频91p| 5566av亚洲| 亚洲欧洲精品天堂一级| 国产理论在线| 亚洲在线观看视频网站| 亚洲欧洲中文日韩久久av乱码| 色黄视频在线观看| 色女人综合av| 精品久久久久一区| 亚洲精品男同| 少妇av一区二区三区| 亚洲综合欧美| 老司机精品影院| 91免费欧美精品| 国产精品久久久久一区二区三区共| 欧美gv在线| 97精品国产97久久久久久粉红| 日韩一级视频免费观看在线| 欧美福利一区| 在线观看免费黄色| 国内视频一区| 欧美一区二区人人喊爽| 99精品国产一区二区青青牛奶| 在线观看完整版免费| 国产在线精品一区二区三区| 欧美一区二区三区视频在线| 国产视频欧美| 成人免费av电影| 国产真人做爰毛片视频直播| 另类美女黄大片| 亚洲欧美日韩国产成人精品影院| 日本欧美视频| 麻豆av在线播放| 黄色网页免费在线观看| 97在线观看免费高清| 精品久久久久久中文字幕| 性一交一乱一区二区洋洋av| 素人啪啪色综合| 日韩欧美国产一区二区三区 | 欧美日韩国产欧| 四虎av在线| 日韩欧美高清在线| xvideos成人免费中文版| 天天综合天天| 亚洲网站在线看| 国产在线国偷精品产拍免费yy| 女囚岛在线观看| 六月婷婷激情综合| 97精品国产91久久久久久| 欧美体内she精视频| 韩国欧美一区二区| 天堂成人娱乐在线视频免费播放网站 | 高清视频一区二区| 日韩欧美自拍| 先锋欧美三级| 欧美日韩伦理片| 国产视频在线视频| 国产麻豆精品视频| 亚洲国产成人精品女人| 日韩一区二区三区高清在线观看| 91ph在线| 最新av免费在线| 男操女免费网站| 国产无限制自拍| 久久精品国产精品国产精品污| 国内成人精品一区| 国产一区二区三区久久精品| 91精品国产综合久久福利软件 | 精品久久久久久久一区二区蜜臀| 一区二区在线观看不卡| 91在线视频18| 日本伊人色综合网| 亚洲精品裸体| 欧美日韩三区| 亚洲自拍偷拍网| 亚洲国产精品综合久久久| 国产日产精品一区二区三区四区的观看方式 | 黄色成人av网| 尤物视频一区二区| 一区二区三区高清在线| 一区二区久久久| 偷拍一区二区三区| 在线精品视频一区二区三四| 成人性爱视频在线观看| 国产精品天堂| gogo在线高清视频| 综合在线影院| 国产精品一区免费在线| 欧美美女黄色| 伊人久久大香线| 日本特黄久久久高潮 | 欧美另类videosbestsex日本| 一区二区精品在线| 亚洲国产精品无码观看久久| 国产精品少妇在线视频| 米奇777在线影院线| 国产福利在线视频| 我爱我色成人网| 婷婷精品在线| 亚洲欧美成人| aaa欧美色吧激情视频| 亚洲一区二区三区免费视频| 精品久久久久99| 午夜精品福利电影| 欧美亚洲精品日韩| 免费无码av片在线观看| 中文在线а天堂av| 美女福利一区二区| 在线不卡日本| 国产又黄又猛又粗| 黄色在线播放网站| 欧美巨大xxxx| 日韩和欧美的一区| 亚洲激情六月丁香| 亚洲欧美成人精品| 国产精品丝袜高跟| 北条麻妃在线视频观看| 黄色网在线播放| 美女视频免费精品| 91香蕉视频mp4| 欧美成人三级电影在线| 欧美性视频精品| 成人免费a级片| 欧洲精品二区| 亚洲第一毛片| 亚洲一区精品在线| 亚洲人成电影网站色…| 国产日产精品一区二区三区四区| 一本久道综合色婷婷五月| 182在线视频观看| 在线观看一区| 在线看一区二区| 成人国产1314www色视频| 国产黄视频网站| 9l视频自拍蝌蚪9l视频成人|