整体设计思路
- 并发调用API:使用
Promise.allSettled
方法并发调用所有API,它会等待所有Promise完成,无论成功或失败,这样可以处理部分API响应时间较长的情况。
- 统一格式整理和校验:针对不同API返回的数据结构,编写不同的整理和校验函数,在API调用成功后调用这些函数处理数据。
- 错误处理:
Promise.allSettled
返回的结果中会包含每个Promise的状态(成功或失败),通过检查状态来处理网络错误和数据格式错误。
- 性能优化:合理设置并发数量,避免因过多并发导致资源耗尽,影响系统稳定性和响应速度。可以使用队列来控制并发数量。
关键代码实现
function fetchData(url) {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.status}`);
}
return response.json();
})
.catch(error => {
console.error('Network error:', error);
return null;
});
}
function validateAndFormatData(data, apiIndex) {
// 这里根据不同API返回的数据结构编写不同的校验和整理逻辑
// 示例:假设某个API返回的数据应该是一个包含'id'和'name'字段的对象
if (apiIndex === 1 && typeof data === 'object' && 'id' in data && 'name' in data) {
return { id: data.id, name: data.name, api: `api - ${apiIndex}.com` };
}
// 其他API的校验和整理逻辑...
console.error(`Data format error for api - ${apiIndex}.com`);
return null;
}
async function main() {
const apiCount = 100;
const apiUrls = Array.from({ length: apiCount }, (_, i) => `https://api - ${i + 1}.com/data`);
const concurrentLimit = 10; // 设置并发数量
const resultQueue = [];
let currentCount = 0;
async function processQueue() {
while (resultQueue.length > 0 && currentCount < concurrentLimit) {
const { url, index } = resultQueue.shift();
currentCount++;
const result = await fetchData(url);
currentCount--;
const formattedData = validateAndFormatData(result, index + 1);
if (formattedData) {
console.log(`Processed data from api - ${index + 1}.com:`, formattedData);
}
}
}
apiUrls.forEach((url, index) => {
resultQueue.push({ url, index });
processQueue();
});
// 等待所有请求处理完
while (currentCount > 0) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
main();