1. 使用Promise.allSettled实现请求控制
function sendHttpRequests(urls, concurrent = 5) {
let currentIndex = 0;
const results = [];
const promises = [];
const sendRequest = () => {
if (currentIndex >= urls.length) {
if (promises.length === 0) {
return Promise.resolve(results);
}
return Promise.allSettled(promises).then(res => {
results.push(...res);
return sendRequest();
});
}
const url = urls[currentIndex++];
const promise = fetch(url).then(response => response.json()).catch(error => error);
promises.push(promise);
if (promises.length >= concurrent) {
return Promise.allSettled(promises).then(res => {
results.push(...res);
promises.length = 0;
return sendRequest();
});
} else {
return sendRequest();
}
};
return sendRequest();
}
// 使用示例
const urls = Array.from({ length: 100 }, (_, i) => `http://example.com/api/${i}`);
sendHttpRequests(urls, 10).then(results => {
console.log(results);
});
2. 避免内存泄漏和资源耗尽问题
- 及时释放资源:在请求完成后,无论是成功还是失败,都要确保相关资源(如网络连接、内存占用等)被正确释放。在上述代码中,
fetch
操作完成后,无论成功与否,Promise.allSettled
都会处理结果,不会造成资源残留。
- 限制并发数量:通过设置合理的并发数量(如上述代码中的
concurrent
参数),避免过多请求同时占用大量资源。例如,同时打开过多的网络连接可能导致系统资源耗尽,限制并发数可以有效避免这种情况。
- 取消请求:对于长时间未响应的请求,可以设置超时机制并提供取消请求的功能。例如,在
fetch
请求时结合AbortController
实现超时取消:
function fetchWithTimeout(url, options = {}, timeout = 5000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
return fetch(url, {...options, signal: controller.signal })
.then(response => {
clearTimeout(id);
return response;
})
.catch(error => {
if (error.name === 'AbortError') {
throw new Error('Request timed out');
}
throw error;
});
}
3. 不同浏览器环境下的兼容性及优化策略
- 兼容性:
Promise.allSettled
在旧版本浏览器(如IE浏览器)中不支持。可以使用polyfill
来解决兼容性问题,例如:
if (!Promise.allSettled) {
Promise.allSettled = function (promises) {
return Promise.all(promises.map(p =>
Promise.resolve(p)
.then(value => ({ status: 'fulfilled', value }))
.catch(reason => ({ status:'rejected', reason }))
));
};
}
- 优化策略:不同浏览器对于并发请求的处理能力和资源限制有所不同。可以通过特性检测来动态调整并发数量,例如在性能较差的浏览器中适当降低并发数。另外,在一些浏览器中,频繁的网络请求可能触发缓存机制,合理利用缓存可以减少不必要的请求,提高性能。例如,可以设置
fetch
请求的cache
选项为'default'
、'no - cache'
、'reload'
等,以控制缓存行为。