關(guān)于promise.all()的使用及說(shuō)明
關(guān)于promise.all()的使用
Promise.all可以將多個(gè)Promise實(shí)例包裝成一個(gè)新的Promise實(shí)例。
同時(shí),成功和失敗的返回值是不同的,成功的時(shí)候返回的是一個(gè)結(jié)果數(shù)組,而失敗的時(shí)候則返回最先被reject失敗狀態(tài)的值。
關(guān)鍵代碼:將所有異步操作存儲(chǔ)到數(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) { ?? ??? ??? ?// 將所有異步操作存儲(chǔ)到數(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] ?? ??? ??? ?}) ?? ??? ?} ?? ?}); }, // 通過(guò)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ā)請(qǐng)求函數(shù)
Promise.all 的簡(jiǎn)單解釋
// 當(dāng)以下數(shù)組中promise1, promise2, promise3都resolve之后,觸發(fā)promise.all的then函數(shù)。 Promise.all([promise1, promise2, promise3]).then((values) => { ? console.log(values); });
需求解釋
所謂并發(fā)請(qǐng)求,即有待請(qǐng)求接口100個(gè),限制每次只能發(fā)出10個(gè)。即同一時(shí)刻最多有10個(gè)正在發(fā)送的請(qǐng)求。
每當(dāng)10個(gè)之中有一個(gè)請(qǐng)求完成,則從待請(qǐng)求的接口中再取出一個(gè)發(fā)出。保證當(dāng)前并發(fā)度仍舊為10。
直至最終請(qǐng)求完成。
設(shè)計(jì)思路
簡(jiǎn)單思路如下:(假設(shè)并發(fā)請(qǐng)求函數(shù)名字為limitedRequest)
- 設(shè)定一個(gè)數(shù)組(命名為:pool),用于后續(xù)Promise.all的使用
- 當(dāng)limitedRequest被調(diào)用的時(shí)候,首先一次性發(fā)出10個(gè)請(qǐng)求,并放入到pool中
- 每一個(gè)請(qǐng)求完成后的回調(diào)函數(shù)中繼續(xù)觸發(fā)下一個(gè)請(qǐng)求,而下一個(gè)請(qǐng)求返回Promise,他的回調(diào)函數(shù)繼續(xù)綁定同樣的回調(diào)函數(shù),即循環(huán)調(diào)用。(看不懂就直接看代碼更易懂)
- 直到全部請(qǐng)求完成,停止。
代碼實(shí)現(xiàn)
具體代碼如下
// 模仿一個(gè)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++) { ? ?? ?// 一次性放入初始的個(gè)數(shù) ? ? pool.push(run(urls.splice(0, 1))); ? } ? // r 代表promise完成的resolve回調(diào)函數(shù) ? // r 函數(shù)無(wú)論什么樣的結(jié)果都返回promise,來(lái)確保最終promise.all可以正確執(zhí)行 ? function r() { ? ? console.log('當(dāng)前并發(fā)度:', pool.length); ? ? if (urls.length === 0) { ? ? ? console.log('并發(fā)請(qǐng)求已經(jīng)全部發(fā)起'); ? ? ? return Promise.resolve(); ? ? } ? ? return run(urls.splice(0, 1)); ? } ? // 調(diào)用一次請(qǐng)求 ? function run(url) { ? ? return mockFetch(url).then(r); ? } ? // 全部請(qǐng)求完成的回調(diào) ? Promise.all(pool).then(() => { ? ? console.log('請(qǐng)求已經(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ā)請(qǐng)求已經(jīng)全部發(fā)起
當(dāng)前并發(fā)度: 3
并發(fā)請(qǐng)求已經(jīng)全部發(fā)起
當(dāng)前并發(fā)度: 3
并發(fā)請(qǐng)求已經(jīng)全部發(fā)起
請(qǐng)求已經(jīng)全部結(jié)束
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(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-03json字符串對(duì)象轉(zhuǎn)換代碼實(shí)例
這篇文章主要介紹了json字符串對(duì)象轉(zhuǎn)換代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09JavaScript面試出現(xiàn)頻繁的一些易錯(cuò)點(diǎn)整理
通過(guò)幾個(gè)常見(jiàn)面試開(kāi)始,討論針對(duì)一個(gè)題目的分析思路,就有了下面這篇文章,本文主要給大家整理總結(jié)介紹了關(guān)于JavaScript面試中會(huì)頻繁出現(xiàn)的一些易錯(cuò)點(diǎn),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧。2018-03-03JS中循環(huán)遍歷數(shù)組的四種方式總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于JS中循環(huán)遍歷數(shù)組的四種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01js實(shí)現(xiàn)日期級(jí)聯(lián)效果
本篇文章主要是對(duì)js實(shí)現(xiàn)日期級(jí)聯(lián)效果的實(shí)例進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01