久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

什么是并發控制?JavaScript中如何實現并發控制?

什么是并發控制?JavaScript中如何實現并發控制?

在日常開發過程中,你可能會遇到并發控制的場景,比如控制請求并發數。那么在 JavaScript 中如何實現并發控制呢?在回答這個問題之前,我們來簡單介紹一下并發控制。

假設有 6 個待辦任務要執行,而我們希望限制同時執行的任務個數,即最多只有 2 個任務能同時執行。當 正在執行任務列表 中的任何 1 個任務完成后,程序會自動從 待辦任務列表 中獲取新的待辦任務并把該任務添加到 正在執行任務列表 中。為了讓大家能夠更直觀地理解上述的過程,阿寶哥特意畫了以下 3 張圖:

1.1 階段一

什么是并發控制?JavaScript中如何實現并發控制?

1.2 階段二

什么是并發控制?JavaScript中如何實現并發控制?

1.3 階段三

什么是并發控制?JavaScript中如何實現并發控制?

好的,介紹完并發控制之后,阿寶哥將以 Github 上 async-pool 這個庫來介紹一下異步任務并發控制的具體實現。

async-pool:https://github.com/rxaviers/async-pool

Run multiple promise-returning & async functions with limited concurrency using native ES6/ES7。

二、并發控制的實現

async-pool 這個庫提供了 ES7 和 ES6 兩種不同版本的實現,在分析其具體實現之前,我們來看一下它如何使用。

2.1 asyncPool 的使用

const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i)); await asyncPool(2, [1000, 5000, 3000, 2000], timeout);

在以上代碼中,我們使用 async-pool 這個庫提供的 asyncPool 函數來實現異步任務的并發控制。 asyncPool 函數的簽名如下所示:

function asyncPool(poolLimit, array, iteratorFn){ ... }

該函數接收 3 個參數:

  • poolLimit(數字類型):表示限制的并發數;
  • array(數組類型):表示任務數組;
  • iteratorFn(函數類型):表示迭代函數,用于實現對每個任務項進行處理,該函數會返回一個 Promise 對象或異步函數。

對于以上示例來說,在使用了 asyncPool 函數之后,對應的執行過程如下所示:

const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i)); await asyncPool(2, [1000, 5000, 3000, 2000], timeout); // Call iterator (i = 1000) // Call iterator (i = 5000) // Pool limit of 2 reached, wait for the quicker one to complete... // 1000 finishes // Call iterator (i = 3000) // Pool limit of 2 reached, wait for the quicker one to complete... // 3000 finishes // Call iterator (i = 2000) // Itaration is complete, wait until running ones complete... // 5000 finishes // 2000 finishes // Resolves, results are passed in given array order `[1000, 5000, 3000, 2000]`.

通過觀察以上的注釋信息,我們可以大致地了解 asyncPool 函數內部的控制流程。下面我們先來分析 asyncPool 函數的 ES7 實現。

關注「全棧修仙之路」閱讀阿寶哥原創的 4 本免費電子書(累計下載 3萬+)及 50 幾篇 TS 系列教程。

2.2 asyncPool ES7 實現

async function asyncPool(poolLimit, array, iteratorFn) {   const ret = []; // 存儲所有的異步任務   const executing = []; // 存儲正在執行的異步任務   for (const item of array) {     // 調用iteratorFn函數創建異步任務     const p = Promise.resolve().then(() => iteratorFn(item, array));     ret.push(p); // 保存新的異步任務      // 當poolLimit值小于或等于總任務個數時,進行并發控制     if (poolLimit <= array.length) {       // 當任務完成后,從正在執行的任務數組中移除已完成的任務       const e = p.then(() => executing.splice(executing.indexOf(e), 1));       executing.push(e); // 保存正在執行的異步任務       if (executing.length >= poolLimit) {         await Promise.race(executing); // 等待較快的任務執行完成       }     }   }   return Promise.all(ret); }

在以上代碼中,充分利用了 Promise.allPromise.race 函數特點,再結合 ES7 中提供的 async await 特性,最終實現了并發控制的功能。利用 await Promise.race(executing); 這行語句,我們會等待 正在執行任務列表 中較快的任務執行完成之后,才會繼續執行下一次循環。

asyncPool ES7 實現相對比較簡單,接下來我們來看一下不使用 async await 特性要如何實現同樣的功能。

2.3 asyncPool ES6 實現

function asyncPool(poolLimit, array, iteratorFn) {   let i = 0;   const ret = []; // 存儲所有的異步任務   const executing = []; // 存儲正在執行的異步任務   const enqueue = function () {     if (i === array.length) {       return Promise.resolve();     }     const item = array[i++]; // 獲取新的任務項     const p = Promise.resolve().then(() => iteratorFn(item, array));     ret.push(p);      let r = Promise.resolve();      // 當poolLimit值小于或等于總任務個數時,進行并發控制     if (poolLimit <= array.length) {       // 當任務完成后,從正在執行的任務數組中移除已完成的任務       const e = p.then(() => executing.splice(executing.indexOf(e), 1));       executing.push(e);       if (executing.length >= poolLimit) {         r = Promise.race(executing);        }     }       // 正在執行任務列表 中較快的任務執行完成之后,才會從array數組中獲取新的待辦任務     return r.then(() => enqueue());   };   return enqueue().then(() => Promise.all(ret)); }

在 ES6 的實現版本中,通過內部封裝的 enqueue 函數來實現核心的控制邏輯。當 Promise.race(executing) 返回的 Promise 對象變成已完成狀態時,才會調用 enqueue 函數,從 array 數組中獲取新的待辦任務。

三、阿寶哥有話說

asyncPool 這個庫的 ES7 和 ES6 的具體實現中,我們都使用到了 Promise.allPromise.race 函數。其中手寫 Promise.all 是一道常見的面試題。剛好趁著這個機會,阿寶哥跟大家一起來手寫簡易版的 Promise.allPromise.race 函數。

3.1 手寫 Promise.all

Promise.all(iterable) 方法會返回一個 promise 對象,當輸入的所有 promise 對象的狀態都變成 resolved 時,返回的 promise 對象就會以數組的形式,返回每個 promise 對象 resolve 后的結果。當輸入的任何一個 promise 對象狀態變成 rejected 時,則返回的 promise 對象會 reject 對應的錯誤信息。

Promise.all = function (iterators) {   return new Promise((resolve, reject) => {     if (!iterators || iterators.length === 0) {       resolve([]);     } else {       let count = 0; // 計數器,用于判斷所有任務是否執行完成       let result = []; // 結果數組       for (let i = 0; i < iterators.length; i++) {         // 考慮到iterators[i]可能是普通對象,則統一包裝為Promise對象         Promise.resolve(iterators[i]).then(           (data) => {             result[i] = data; // 按順序保存對應的結果             // 當所有任務都執行完成后,再統一返回結果             if (++count === iterators.length) {               resolve(result);             }           },           (err) => {             reject(err); // 任何一個Promise對象執行失敗,則調用reject()方法             return;           }         );       }     }   }); };

需要注意的是對于 Promise.all 的標準實現來說,它的參數是一個可迭代對象,比如 Array、String 或 Set 等。

3.2 手寫 Promise.race

Promise.race(iterable) 方法會返回一個 promise 對象,一旦迭代器中的某個 promise 對象 resolvedrejected,返回的 promise 對象就會 resolve 或 reject 相應的值。

Promise.race = function (iterators) {   return new Promise((resolve, reject) => {     for (const iter of iterators) {       Promise.resolve(iter)         .then((res) => {           resolve(res);         })         .catch((e) => {           reject(e);         });     }   }); };

本文阿寶哥帶大家詳細分析了 async-pool 異步任務并發控制的具體實現,同時為了讓大家能夠更好地理解 async-pool 的核心代碼。最后阿寶哥還帶大家一起手寫簡易版的 Promise.allPromise.race 函數。其實除了 Promise.all 函數之外,還存在另一個函數 —— Promise.allSettled,該函數用于解決 Promise.all 存在的問題,感興趣的小伙伴可以自行研究一下。

四、參考資源

  • Github – async-pool
  • MDN – Promise.all
  • MDN – Promise.race
  • MDN – Promise.allSettled

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
欧美三级第一页| 日韩av不卡一区二区| 国产不卡av一区二区| 国产综合色区在线观看| 免费av一区二区三区四区| 日韩亚洲国产欧美| 日本中文字幕一区二区| 国产成人免费av一区二区午夜| 天堂√8在线中文| 日韩欧美精品一区二区综合视频| 麻豆精品蜜桃| 日韩激情综合| 五月天久久网站| 久久影院一区二区三区| 国产精品黑丝在线播放| 美女久久精品| 天堂中文在线播放| 国产成人精品一区二区三区在线| 日本伊人久久| 亚洲精品伊人| 日韩美女精品| 日韩国产在线观看一区| 日韩精品一区二区三区免费视频| 日韩精品水蜜桃| 国产精品日本一区二区三区在线| 丰满少妇一区| 国产欧美日韩视频在线 | 亚洲v在线看| 国产精品中文字幕制服诱惑| 1024精品久久久久久久久| 日韩精品一二三四| 久久香蕉精品香蕉| 亚洲性色av| 一区二区三区四区日韩| 亚洲激情社区| 国产亚洲亚洲| 亚洲一区二区三区高清| 99久久久久久中文字幕一区| 免费在线成人| 久久99精品久久久野外观看| 香蕉成人久久| 日本精品不卡| 国产精选在线| 日本精品久久| 精品视频自拍| 日韩精品欧美精品| 四虎在线精品| 精品久久电影| 亚洲黑丝一区二区| 亚洲bt欧美bt精品777| 免费在线观看一区二区三区| 亚洲一区二区免费看| 99精品一区| 久久wwww| 韩日一区二区三区| 麻豆一区二区三区| 99久久精品费精品国产| 午夜久久黄色| 亚洲毛片网站| 一区久久精品| 亚洲乱码视频| 亚洲18在线| 欧美成人基地| 日韩精品欧美成人高清一区二区| 91精品麻豆| 精品欧美一区二区三区在线观看| 欧美va天堂在线| 国产精品色网| 日韩有吗在线观看| 亚洲精品91| 亚洲精品国产日韩| 午夜亚洲福利| 国产精品久久久久av蜜臀 | 国产精品毛片久久| 国产精品腿扒开做爽爽爽挤奶网站| 九九综合在线| 日韩欧美一区二区三区免费看| 国产91欧美| 97精品国产| 亚洲一区久久| 国产一区二区三区四区大秀| 久久香蕉精品| 亚洲性色av| 久久精品毛片| 午夜天堂精品久久久久| 中文在线免费视频| 午夜在线精品偷拍| 国产精品伦一区二区| 群体交乱之放荡娇妻一区二区| 亚洲综合不卡| 一区二区精彩视频| 鲁大师成人一区二区三区| 久久久久国产| 国产精品嫩模av在线| 亚洲免费影院| 97国产精品| 日韩高清欧美激情| 热久久国产精品| 欧美精品二区| 国产aⅴ精品一区二区四区| 久久亚州av| 国产网站在线| 日韩精品第一| 日本特黄久久久高潮| 免费在线小视频| 中文在线免费视频| 日韩国产高清在线| 婷婷亚洲综合| 国产精品一区二区三区四区在线观看 | 久久gogo国模啪啪裸体| 亚洲三区欧美一区国产二区| 亚洲综合二区| 婷婷激情久久| 久久精品99久久无色码中文字幕| 久久精品国产福利| 欧美激情日韩| 美女国产精品久久久| 久久男女视频| 在线观看视频免费一区二区三区| 给我免费播放日韩视频| 亚洲精品系列| 欧美日韩国产在线一区| 欧美激情99| 婷婷成人av| 99视频一区| 国产suv精品一区| 亚洲精品裸体| 99久久精品费精品国产| 国产精品国码视频| 老牛国产精品一区的观看方式| 吉吉日韩欧美| 老鸭窝亚洲一区二区三区| 日韩中文首页| 国产精品亲子伦av一区二区三区 | 久久国产乱子精品免费女| 天堂√中文最新版在线| 日韩欧美精品综合| 日韩精品高清不卡| 精品一区二区三区中文字幕在线| 成人综合一区| 亚洲精华国产欧美| 亚洲综合在线电影| 日韩美女精品| 久久精品72免费观看| 高清日韩欧美| 免费视频一区二区三区在线观看| 欧美日韩国产综合网| 国产一区二区视频在线看| 99久久精品国产亚洲精品| 免费视频最近日韩| 福利精品一区| 日韩综合在线| 国产一区二区色噜噜| av亚洲免费| 精品国产中文字幕第一页| 青青草91视频| 欧美视频精品全部免费观看| 日韩毛片网站| 亚洲一区二区三区高清| 欧美粗暴jizz性欧美20| 在线看片不卡| 亚洲精品一区二区妖精| 九九久久国产| 国产欧美日韩在线一区二区| 影院欧美亚洲| 亚洲一区二区动漫| 精品日韩视频| 欧美1级日本1级| 久久中文视频| 国产精品中文字幕亚洲欧美 | 国产精品2区| 69堂精品视频在线播放| 国产美女久久| 最新中文字幕在线播放| 91久久亚洲| 日韩一区二区久久| 欧美精品一区二区久久| 蜜桃精品在线| 久久精品国内一区二区三区水蜜桃| 日韩欧美二区| 中文字幕人成乱码在线观看| 国产成人久久精品麻豆二区| 国产精品久久久久毛片大屁完整版 | 日韩欧美四区| 国产亚洲一区二区三区啪| 美女久久99| 综合国产精品| 国产一二在线播放| 精品视频国内| 久久国产电影| 国产亚洲一区| 视频一区中文| 日本va欧美va欧美va精品| 日韩av资源网| 天堂av在线| 午夜一区在线| 国产精品密蕾丝视频下载| 日韩亚洲在线| 9999国产精品| 免费看欧美美女黄的网站|