您好,登錄后才能下訂單哦!
這篇文章給大家介紹怎么在JavaScript中使用Promise控制并發(fā)請(qǐng)求個(gè)數(shù),內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
串行:一個(gè)異步請(qǐng)求完了之后在進(jìn)行下一個(gè)請(qǐng)求
并行:多個(gè)異步請(qǐng)求同時(shí)進(jìn)行
串行舉例:
var p = function () { return new Promise(function (resolve, reject) { setTimeout(() => { console.log("1000"); resolve(); }, 1000); }); }; var p1 = function () { return new Promise(function (resolve, reject) { setTimeout(() => { console.log("2000"); resolve(); }, 2000); }); }; var p2 = function () { return new Promise(function (resolve, reject) { setTimeout(() => { console.log("3000"); resolve(); }, 3000); }); }; p() .then(() => { return p1(); }) .then(() => { return p2(); }) .then(() => { console.log("end"); });
如示例,串行會(huì)從上到下依次執(zhí)行對(duì)應(yīng)接口請(qǐng)求。
并行舉例:
通常,我們?cè)谛枰WC代碼在多個(gè)異步處理之后執(zhí)行,會(huì)用到:
Promise.all((promises: [])).then((fun: function));
Promise.all可以保證,promises數(shù)組中所有promise對(duì)象都達(dá)到resolve狀態(tài),才執(zhí)行then回調(diào)。
var promises = function () { return [1000, 2000, 3000].map((current) => { return new Promise(function (resolve, reject) { setTimeout(() => { console.log(current); }, current); }); }); }; Promise.all(promises()).then(() => { console.log("end"); });
這時(shí)候考慮一個(gè)場(chǎng)景:
如果你的promises數(shù)組中每個(gè)對(duì)象都是http請(qǐng)求,而這樣的對(duì)象有幾十萬(wàn)個(gè)。
那么會(huì)出現(xiàn)的情況是,你在瞬間發(fā)出幾十萬(wàn)個(gè)http請(qǐng)求,這樣很有可能導(dǎo)致堆積了無(wú)數(shù)調(diào)用棧導(dǎo)致內(nèi)存溢出。
這時(shí)候,我們就需要考慮對(duì)Promise.all做并發(fā)限制。
Promise.all并發(fā)限制指的是,每個(gè)時(shí)刻并發(fā)執(zhí)行的promise數(shù)量是固定的,最終的執(zhí)行結(jié)果還是保持與原來(lái)的Promise.all一致。
整體采用遞歸調(diào)用來(lái)實(shí)現(xiàn):最初發(fā)送的請(qǐng)求數(shù)量上限為允許的最大值,并且這些請(qǐng)求中的每一個(gè)都應(yīng)該在完成時(shí)繼續(xù)遞歸發(fā)送,通過(guò)傳入的索引來(lái)確定了urls里面具體是那個(gè)URL,保證最后輸出的順序不會(huì)亂,而是依次輸出。
代碼:
function multiRequest(urls, maxNum) { const len = urls.length; // 請(qǐng)求總數(shù)量 const res = new Array(len).fill(0); // 請(qǐng)求結(jié)果數(shù)組 let sendCount = 0; // 已發(fā)送的請(qǐng)求數(shù)量 let finishCount = 0; // 已完成的請(qǐng)求數(shù)量 return new Promise((resolve, reject) => { // 首先發(fā)送 maxNum 個(gè)請(qǐng)求,注意:請(qǐng)求數(shù)可能小于 maxNum,所以也要滿足條件2 // 同步的 創(chuàng)建maxNum個(gè)next并行請(qǐng)求 然后才去執(zhí)行異步的fetch 所以一上來(lái)就有5個(gè)next并行執(zhí)行 while (sendCount < maxNum && sendCount < len) { next(); } function next () { let current = sendCount ++; // 當(dāng)前發(fā)送的請(qǐng)求數(shù)量,后加一 保存當(dāng)前請(qǐng)求url的位置 // 遞歸出口 if (finishCount >= len) { // 如果所有請(qǐng)求完成,則解決掉 Promise,終止遞歸 resolve(res); return; } const url = urls[current]; fetch(url).then(result => { finishCount ++; res[current] = result; if (current < len) { // 如果請(qǐng)求沒(méi)有發(fā)送完,繼續(xù)發(fā)送請(qǐng)求 next(); } }, err => { finishCount ++; res[current] = err; if (current < len) { // 如果請(qǐng)求沒(méi)有發(fā)送完,繼續(xù)發(fā)送請(qǐng)求 next(); } }); } }); }
1.可以使網(wǎng)頁(yè)具有交互性,例如響應(yīng)用戶點(diǎn)擊,給用戶提供更好的體驗(yàn)。 2.可以處理表單,檢驗(yàn)用戶的輸入,并提供及時(shí)反饋節(jié)省用戶時(shí)間。 3.可以根據(jù)用戶的操作,動(dòng)態(tài)的創(chuàng)建頁(yè)面。 4使用JavaScript可以通過(guò)設(shè)置cookie存儲(chǔ)在瀏覽器上的一些臨時(shí)信息。
關(guān)于怎么在JavaScript中使用Promise控制并發(fā)請(qǐng)求個(gè)數(shù)就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。