關(guān)于promise.all()的使用及說明
關(guān)于promise.all()的使用
Promise.all可以將多個Promise實(shí)例包裝成一個新的Promise實(shí)例。
同時,成功和失敗的返回值是不同的,成功的時候返回的是一個結(jié)果數(shù)組,而失敗的時候則返回最先被reject失敗狀態(tài)的值。
關(guān)鍵代碼:將所有異步操作存儲到數(shù)組pros中,Promise.all(pros)執(zhí)行所有異步操作
let pros = [] data.forEach(element => { ?? ?pros.push( this.getJsonFile(element.json,element.fileName) ) }); Promise.all(pros).then(val => { ?? ?this.fontsList = [...val] })
示例:
// 獲取字體所有json文件展示 getIconFonts(isFresh) { ?? ?req.post(window.context.uc+`/system/file/v1/queryIconFiles`).then(rep => { ?? ??? ?if(rep && rep.data) { ?? ??? ??? ?// 將所有異步操作存儲到數(shù)組pros中 ?? ??? ??? ?let pros = [] ?? ??? ??? ?data.forEach(element => { ?? ??? ??? ??? ?pros.push( this.getJsonFile(element.json,element.fileName) ) ?? ??? ??? ?}); ?? ??? ??? ?// 執(zhí)行所有異步操作后處理數(shù)據(jù) ?? ??? ??? ?Promise.all(pros).then(val => { ?? ??? ??? ??? ?this.fontsList = [...val] ?? ??? ??? ??? ?this.uploadFonts = [...this.fontsList] ?? ??? ??? ?}) ?? ??? ?} ?? ?}); }, // 通過id獲取json文件 getJsonFile(fileId, fileName) { ?? ?return new Promise((resolve, reject) => { ?? ??? ?req.get(window.context.uc +'/system/file/v1/preview?fileId=' + fileId).then(rep => { ?? ??? ??? ?if(rep && rep.data) { ?? ??? ??? ??? ?let data = { ?? ??? ??? ??? ??? ?fileName, ?? ??? ??? ??? ??? ?...rep.data ?? ??? ??? ??? ?} ?? ??? ??? ??? ?// 返回處理后的數(shù)據(jù) ?? ??? ??? ??? ?resolve(data) ?? ??? ??? ?} ?? ??? ?}) ?? ?}) }
Promise.all實(shí)現(xiàn)限制并發(fā)請求函數(shù)
Promise.all 的簡單解釋
// 當(dāng)以下數(shù)組中promise1, promise2, promise3都resolve之后,觸發(fā)promise.all的then函數(shù)。 Promise.all([promise1, promise2, promise3]).then((values) => { ? console.log(values); });
需求解釋
所謂并發(fā)請求,即有待請求接口100個,限制每次只能發(fā)出10個。即同一時刻最多有10個正在發(fā)送的請求。
每當(dāng)10個之中有一個請求完成,則從待請求的接口中再取出一個發(fā)出。保證當(dāng)前并發(fā)度仍舊為10。
直至最終請求完成。
設(shè)計(jì)思路
簡單思路如下:(假設(shè)并發(fā)請求函數(shù)名字為limitedRequest)
- 設(shè)定一個數(shù)組(命名為:pool),用于后續(xù)Promise.all的使用
- 當(dāng)limitedRequest被調(diào)用的時候,首先一次性發(fā)出10個請求,并放入到pool中
- 每一個請求完成后的回調(diào)函數(shù)中繼續(xù)觸發(fā)下一個請求,而下一個請求返回Promise,他的回調(diào)函數(shù)繼續(xù)綁定同樣的回調(diào)函數(shù),即循環(huán)調(diào)用。(看不懂就直接看代碼更易懂)
- 直到全部請求完成,停止。
代碼實(shí)現(xiàn)
具體代碼如下
// 模仿一個fetch的異步函數(shù),返回promise function mockFetch(param) { ? return new Promise((resovle) => { ? ? setTimeout(() => { ? ? ? resovle(param); ? ? }, 2000); ? }); } function limitedRequest(urls, maxNum) { ? const pool = []; ? // 處理maxNum比urls.length 還要大的情況。 ? const initSize = Math.min(urls.length, maxNum); ? for (let i = 0; i < initSize; i++) { ? ?? ?// 一次性放入初始的個數(shù) ? ? pool.push(run(urls.splice(0, 1))); ? } ? // r 代表promise完成的resolve回調(diào)函數(shù) ? // r 函數(shù)無論什么樣的結(jié)果都返回promise,來確保最終promise.all可以正確執(zhí)行 ? function r() { ? ? console.log('當(dāng)前并發(fā)度:', pool.length); ? ? if (urls.length === 0) { ? ? ? console.log('并發(fā)請求已經(jīng)全部發(fā)起'); ? ? ? return Promise.resolve(); ? ? } ? ? return run(urls.splice(0, 1)); ? } ? // 調(diào)用一次請求 ? function run(url) { ? ? return mockFetch(url).then(r); ? } ? // 全部請求完成的回調(diào) ? Promise.all(pool).then(() => { ? ? console.log('請求已經(jīng)全部結(jié)束'); ? }); } // 函數(shù)調(diào)用 limitedRequest([1, 2, 3, 4, 5, 6, 7, 8], 3);
# 最終返回結(jié)果
$ node .\src\views\doc\detail\index.js
當(dāng)前并發(fā)度: 3
當(dāng)前并發(fā)度: 3
當(dāng)前并發(fā)度: 3
當(dāng)前并發(fā)度: 3
當(dāng)前并發(fā)度: 3
當(dāng)前并發(fā)度: 3
并發(fā)請求已經(jīng)全部發(fā)起
當(dāng)前并發(fā)度: 3
并發(fā)請求已經(jīng)全部發(fā)起
當(dāng)前并發(fā)度: 3
并發(fā)請求已經(jīng)全部發(fā)起
請求已經(jīng)全部結(jié)束
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
javascript 中的 delete及delete運(yùn)算符
這篇文章主要介紹了javascript 中的 delete及delete運(yùn)算符的相關(guān)資料,需要的朋友可以參考下2015-11-11javascript學(xué)習(xí)隨筆(使用window和frame)的技巧
javascript學(xué)習(xí)隨筆(使用window和frame)的技巧...2007-03-03JavaScript面試出現(xiàn)頻繁的一些易錯點(diǎn)整理
通過幾個常見面試開始,討論針對一個題目的分析思路,就有了下面這篇文章,本文主要給大家整理總結(jié)介紹了關(guān)于JavaScript面試中會頻繁出現(xiàn)的一些易錯點(diǎn),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起看看吧。2018-03-03JS中循環(huán)遍歷數(shù)組的四種方式總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于JS中循環(huán)遍歷數(shù)組的四種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01