MST

星途 面试题库

面试题:JavaScript函数定义在高并发场景下的深度适配与性能调优

在高并发场景中,比如同时发起100个HTTP请求,如何通过合理定义JavaScript函数来优化性能并确保请求有序或并发执行的控制?使用Promise.allSettled结合函数定义实现此场景,并阐述如何避免因高并发导致的内存泄漏和资源耗尽问题,同时分析在不同浏览器环境下可能出现的兼容性及优化策略。
23.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

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'等,以控制缓存行为。