JavaScript前端控制網絡并發(fā)數目的常見方法小結
在現代Web應用開發(fā)中,提高用戶體驗的同時要確保服務器負載平衡是至關重要的??刂魄岸税l(fā)起請求的并發(fā)數,即限制同一時間內進行處理的請求數量,是一種有效的策略。本文將詳細介紹前端控制并發(fā)數的幾種常見做法,并且提供具體的代碼示例。
隊列機制
隊列是實現并發(fā)控制常用的數據結構。它遵循先進先出(FIFO)的原則,能夠按照請求到達的順序逐一處理。
示例:基于 Promise 的請求隊列
在JavaScript中,可以利用Promise
來實現一個簡單的請求隊列。下面是一個示例代碼:
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ā):
// 實例化隊列,設置最大并發(fā)數為 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ā)數:
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 => { // 處理結果 });
在上述代碼中,limit
函數會保證同時只有兩個請求在處理。
XMLHttpRequest的abort方法
在使用XMLHttpRequest(XHR)對象發(fā)送請求時,可以在請求數量超過設定的并發(fā)限制時調用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函數對并發(fā)數目進行校驗,去除超過的部分。
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ā)數,避免服務器過載且優(yōu)化用戶體驗。不需修改服務器配置或縮放服務器資源即可實現前端請求的優(yōu)雅管理。這些策略對于構建響應速度快、資源使用高效的Web應用至關重要。
以上就是JavaScript前端控制網絡并發(fā)數目的常見方法小結的詳細內容,更多關于JavaScript控制網絡并發(fā)的資料請關注腳本之家其它相關文章!
相關文章
JS處理數據四舍五入(tofixed與round的區(qū)別詳解)
下面小編就為大家?guī)硪黄狫S處理數據四舍五入(tofixed與round的區(qū)別詳解)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10