MST

星途 面试题库

面试题:JavaScript高并发场景下的资源限制与调度

在JavaScript环境中,假设有大量(例如1000个)返回Promise的函数需要并发执行,但系统资源有限,同一时间只能允许10个函数并发执行。请设计一个高效的调度方案,使得所有函数都能成功执行,并且尽可能快地完成,同时要考虑错误处理和执行结果的收集,最后输出整体执行时间和每个函数的执行结果。
37.8万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
function runTasks(tasks, maxConcurrent) {
    return new Promise((resolve, reject) => {
        const results = [];
        let completedCount = 0;
        const startTime = Date.now();
        let currentIndex = 0;

        function executeNext() {
            while (results.length - completedCount < maxConcurrent && currentIndex < tasks.length) {
                const task = tasks[currentIndex++];
                task()
                   .then(result => {
                        results.push(result);
                        completedCount++;
                        if (completedCount === tasks.length) {
                            const endTime = Date.now();
                            resolve({
                                totalTime: endTime - startTime,
                                results
                            });
                        } else {
                            executeNext();
                        }
                    })
                   .catch(error => {
                        reject(error);
                    });
            }
        }

        executeNext();
    });
}

// 示例任务函数
const taskFunctions = Array.from({ length: 1000 }, (_, i) => () => new Promise((resolve) => {
    setTimeout(() => {
        resolve(`Task ${i} completed`);
    }, Math.random() * 1000);
}));

runTasks(taskFunctions, 10)
   .then(result => {
        console.log(`整体执行时间: ${result.totalTime} ms`);
        console.log(`每个函数的执行结果:`, result.results);
    })
   .catch(error => {
        console.error('执行过程中出错:', error);
    });
  1. 原理
    • runTasks函数接受任务数组tasks和最大并发数maxConcurrent
    • results数组用于收集每个任务的执行结果,completedCount记录已完成的任务数,startTime记录开始执行时间。
    • executeNext函数负责在当前并发任务数未满且还有任务待执行时,启动新的任务。每个任务执行完成后,将结果加入results,更新完成计数。如果所有任务都完成,计算总执行时间并返回结果。
    • 如果任务执行过程中出现错误,通过reject传递错误信息。
  2. 示例使用
    • 创建了1000个模拟任务,每个任务随机延迟0到1000毫秒后返回结果。
    • 调用runTasks函数,设置最大并发数为10,并处理最终的结果和错误。