JS实现并发请求
使用Promise.all实现并发请求
Promise.all可以同时发起多个异步请求,并在所有请求完成后统一处理结果。该方法适用于需要同时获取多个独立数据的场景。
const urls = ['url1', 'url2', 'url3'];
const requests = urls.map(url => fetch(url));
Promise.all(requests)
.then(responses => Promise.all(responses.map(res => res.json())))
.then(data => console.log(data))
.catch(error => console.error('请求失败:', error));
限制并发数量的实现
当需要控制同时进行的请求数量时,可以使用以下方法。这种方式适合避免服务器过载或浏览器限制的情况。
async function concurrentRequests(urls, maxConcurrent) {
const results = [];
const executing = new Set();
for (const url of urls) {
const promise = fetch(url).then(res => res.json());
results.push(promise);
executing.add(promise);
promise.finally(() => executing.delete(promise));
if (executing.size >= maxConcurrent) {
await Promise.race(executing);
}
}
return Promise.all(results);
}
// 使用示例
concurrentRequests(['url1', 'url2', 'url3'], 2)
.then(data => console.log(data));
使用async/await的并发处理
结合async/await语法可以更清晰地编写并发请求代码。这种方式代码可读性更好,适合现代JavaScript开发。
async function fetchAllUrls(urls) {
try {
const responses = await Promise.all(
urls.map(url => fetch(url).then(res => res.json()))
);
console.log(responses);
} catch (error) {
console.error('请求出错:', error);
}
}
fetchAllUrls(['url1', 'url2', 'url3']);
处理失败请求的策略
在实际应用中,可能需要处理部分请求失败的情况,而不是全部失败。以下方法允许部分请求失败而不影响其他请求。
async function fetchWithFallback(urls) {
const results = await Promise.allSettled(
urls.map(url => fetch(url).then(res => res.json()))
);
const successful = results
.filter(result => result.status === 'fulfilled')
.map(result => result.value);
const failed = results
.filter(result => result.status === 'rejected')
.map(result => result.reason);
console.log('成功:', successful);
console.log('失败:', failed);
}
使用AbortController取消请求
在需要取消请求的场景下,可以使用AbortController来中止正在进行的请求。这对于用户主动取消或超时处理很有用。
const controller = new AbortController();
const { signal } = controller;
// 设置超时自动取消
const timeoutId = setTimeout(() => controller.abort(), 5000);
fetch('url', { signal })
.then(res => res.json())
.then(data => {
clearTimeout(timeoutId);
console.log(data);
})
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被取消');
} else {
console.error('请求出错:', err);
}
});






