const urls = ['https://url1.com/api', 'https://url2.com/api', 'https://url3.com/api'];
const fetchWithTimeout = (url, options = {}, timeout = 5000) => {
return new Promise((resolve, reject) => {
const controller = new AbortController();
const { signal } = controller;
const timeoutId = setTimeout(() => controller.abort(), timeout);
fetch(url, {...options, signal })
.then(response => {
clearTimeout(timeoutId);
resolve(response);
})
.catch(error => {
if (error.name === 'AbortError') {
reject(new Error('请求超时'));
} else {
reject(error);
}
});
});
};
Promise.all(urls.map(url => fetchWithTimeout(url)))
.then(responses => Promise.all(responses.map(response => response.json())))
.then(data => {
// 合并处理结果
const mergedData = data.reduce((acc, cur) => {
// 这里假设cur是一个对象,可以根据实际数据结构合并
return {...acc, ...cur };
}, {});
console.log(mergedData);
})
.catch(error => {
console.error('请求出错:', error);
});
优化思路
- 请求超时:通过
AbortController
和 setTimeout
实现请求超时机制,在 fetch
中传入 signal
来控制请求的终止。
- 并发控制:如果URL数量非常多,可以使用队列控制并发请求数量,避免过多请求导致资源耗尽。例如可以使用
async/await
结合 Promise
实现简单的队列,每次只处理固定数量的请求,处理完一批再处理下一批。
- 错误处理:在
fetchWithTimeout
中捕获超时错误和其他 fetch
错误,确保错误信息能够准确反馈。同时在 Promise.all
中也对错误进行捕获,防止某个请求失败导致整个流程中断而无法处理其他请求结果。