MST

星途 面试题库

面试题:JavaScript在高并发API调用与复杂数据处理场景下的优化

假设有一个场景,需要同时调用100个不同的API(每个API地址格式为'https://api - {n}.com/data',n从1到100),这些API返回的数据结构各不相同,并且可能存在部分API响应时间较长的情况。要求使用JavaScript编写代码实现以下功能:1. 尽可能高效地并发调用这些API;2. 对返回的数据进行统一格式的整理和校验;3. 处理可能出现的各种网络错误和数据格式错误;4. 优化代码性能,确保在高并发情况下系统的稳定性和响应速度。请阐述你的整体设计思路,并给出关键代码实现。
50.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

整体设计思路

  1. 并发调用API:使用Promise.allSettled方法并发调用所有API,它会等待所有Promise完成,无论成功或失败,这样可以处理部分API响应时间较长的情况。
  2. 统一格式整理和校验:针对不同API返回的数据结构,编写不同的整理和校验函数,在API调用成功后调用这些函数处理数据。
  3. 错误处理Promise.allSettled返回的结果中会包含每个Promise的状态(成功或失败),通过检查状态来处理网络错误和数据格式错误。
  4. 性能优化:合理设置并发数量,避免因过多并发导致资源耗尽,影响系统稳定性和响应速度。可以使用队列来控制并发数量。

关键代码实现

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();