JavaScript前端控制網(wǎng)絡(luò)并發(fā)數(shù)目的常見方法小結(jié)
在現(xiàn)代Web應(yīng)用開發(fā)中,提高用戶體驗的同時要確保服務(wù)器負(fù)載平衡是至關(guān)重要的??刂魄岸税l(fā)起請求的并發(fā)數(shù),即限制同一時間內(nèi)進(jìn)行處理的請求數(shù)量,是一種有效的策略。本文將詳細(xì)介紹前端控制并發(fā)數(shù)的幾種常見做法,并且提供具體的代碼示例。
隊列機(jī)制
隊列是實現(xiàn)并發(fā)控制常用的數(shù)據(jù)結(jié)構(gòu)。它遵循先進(jìn)先出(FIFO)的原則,能夠按照請求到達(dá)的順序逐一處理。
示例:基于 Promise 的請求隊列
在JavaScript中,可以利用Promise來實現(xiàn)一個簡單的請求隊列。下面是一個示例代碼:
class PromiseQueue {
constructor(maxConcurrent) {
this.maxConcurrent = maxConcurrent;
this.queue = [];
this.currentCount = 0;
}
add(promiseCreator) {
return new Promise((resolve, reject) => {
this.queue.push({
promiseCreator,
resolve,
reject
});
this.tryToRun();
});
}
tryToRun() {
if (this.queue.length === 0 || this.currentCount >= this.maxConcurrent) {
return;
}
this.currentCount++;
const { promiseCreator, resolve, reject } = this.queue.shift();
promiseCreator().then(resolve, reject).finally(() => {
this.currentCount--;
this.tryToRun();
});
}
}
利用此隊列可以如下方式控制并發(fā):
// 實例化隊列,設(shè)置最大并發(fā)數(shù)為 2 const queue = new PromiseQueue(2); // 添加請求到隊列 queue.add(() => fetch(url1)).then(handleResponse); queue.add(() => fetch(url2)).then(handleResponse); queue.add(() => fetch(url3)).then(handleResponse);
在此示例中,只有兩個請求會立即執(zhí)行,第三個請求會等待前兩個中的某個完成后再開始。
控制并發(fā)的庫
市面上有許多專門用于控制并發(fā)的JavaScript庫,如p-limit, async等。
示例:使用 p-limit 控制并發(fā)
p-limit是一個輕量級的庫,可以方便地限制并發(fā)數(shù):
import pLimit from 'p-limit';
const limit = pLimit(2);
const input = [
limit(() => fetch(url1)),
limit(() => fetch(url2)),
limit(() => fetch(url3)),
limit(() => fetch(url4)),
];
// 只有 2 個請求被同時處理
Promise.all(input).then(results => {
// 處理結(jié)果
});
在上述代碼中,limit函數(shù)會保證同時只有兩個請求在處理。
XMLHttpRequest的abort方法
在使用XMLHttpRequest(XHR)對象發(fā)送請求時,可以在請求數(shù)量超過設(shè)定的并發(fā)限制時調(diào)用abort方法來取消請求。
示例:使用XMLHttpRequest和abort控制并發(fā)
const MAX_CONCURRENT = 2;
let concurrentCount = 0;
const xhrPool = [];
function fetchWithXhr(url) {
if (concurrentCount >= MAX_CONCURRENT) {
setTimeout(() => fetchWithXhr(url), 200); // 200ms 后重試
return;
}
concurrentCount++;
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => {
handleResponse(xhr.response);
concurrentCount--;
if (xhrPool.length > 0) {
const newXhr = xhrPool.shift();
fetchWithXhr(newXhr.url);
}
};
xhr.onerror = xhr.onabort = () => {
concurrentCount--;
};
xhr.send();
}
function abortExtraRequests() {
while (concurrentCount > MAX_CONCURRENT) {
const xhrToAbort = xhrPool.pop();
xhrToAbort.abort();
}
}
// 發(fā)起請求
fetchWithXhr("https://api.example.com/data1");
fetchWithXhr("https://api.example.com/data2");
fetchWithXhr("https://api.example.com/data3");
在此示例中,超出并發(fā)限制的請求將會被推遲執(zhí)行,而非立即取消;并且可以使用abortExtraRequests函數(shù)對并發(fā)數(shù)目進(jìn)行校驗,去除超過的部分。
Fetch API的AbortController
Fetch API提供了AbortController接口,通過它可以隨時取消一個或多個請求。
示例:使用AbortController控制并發(fā)
const MAX_CONCURRENT = 2;
let concurrentCount = 0;
const controllerQueue = new Map();
async function fetchWithAbortController(url) {
if (concurrentCount >= MAX_CONCURRENT) {
await new Promise(resolve => setTimeout(resolve, 200)); // 200ms 后重試
return fetchWithAbortController(url);
}
const controller = new AbortController();
concurrentCount++;
controllerQueue.set(url, controller);
try {
const response = await fetch(url, { signal: controller.signal });
handleResponse(await response.json());
} catch (error) {
// 錯誤處理
} finally {
controllerQueue.delete(url);
concurrentCount--;
if (__yourCondition) {
controllerQueue.get(__specificUrl).abort(); // 取消下一個請求
}
}
}
// 發(fā)起請求
fetchWithAbortController("https://api.example.com/data1");
fetchWithAbortController("https://api.example.com/data2");
fetchWithAbortController("https://api.example.com/data3");
在這個例子中,AbortController用于取消等待隊列中的請求,而且每個請求都有自己的AbortController實例。
通過以上方法,可以有效控制前端并發(fā)數(shù),避免服務(wù)器過載且優(yōu)化用戶體驗。不需修改服務(wù)器配置或縮放服務(wù)器資源即可實現(xiàn)前端請求的優(yōu)雅管理。這些策略對于構(gòu)建響應(yīng)速度快、資源使用高效的Web應(yīng)用至關(guān)重要。
以上就是JavaScript前端控制網(wǎng)絡(luò)并發(fā)數(shù)目的常見方法小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript控制網(wǎng)絡(luò)并發(fā)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS處理數(shù)據(jù)四舍五入(tofixed與round的區(qū)別詳解)
下面小編就為大家?guī)硪黄狫S處理數(shù)據(jù)四舍五入(tofixed與round的區(qū)別詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
javascript實現(xiàn)保留兩位小數(shù)的多種方法
這篇文章主要介紹了javascript實現(xiàn)保留兩位小數(shù)的多種方法,如果數(shù)字的原本小數(shù)位數(shù)不到兩位,那么缺少的就自動補零,感興趣的小伙伴們可以參考一下2015-12-12
javascript實現(xiàn)漢字轉(zhuǎn)拼音代碼分享
這篇文章主要介紹了javascript實現(xiàn)漢字轉(zhuǎn)拼音代碼分享,非常的實用,從項目中分離出來的,這里分享給大家,有需要的小伙伴可以參考下。2015-04-04

