MST

星途 面试题库

面试题:Node.js并发控制策略在高并发场景下的应用

在一个高并发的Node.js应用中,有100个需要并发执行的异步任务,但由于系统资源限制,只能同时执行10个任务。请阐述你会采用什么样的并发控制策略来处理这种情况,并给出实现代码示例(可基于Promise或其他异步处理方式)。同时说明如何优雅地处理任务失败和错误恢复。
26.7万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试
  1. 并发控制策略
    • 采用队列的方式,将100个任务放入队列中,每次从队列中取出10个任务并发执行,当有任务完成时,再从队列中取出新的任务执行,直到所有任务执行完毕。
  2. 基于Promise的实现代码示例
function asyncTask(taskId) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (Math.random() > 0.1) { // 模拟10%的失败率
                console.log(`Task ${taskId} completed`);
                resolve(taskId);
            } else {
                console.log(`Task ${taskId} failed`);
                reject(new Error(`Task ${taskId} failed`));
            }
        }, Math.floor(Math.random() * 1000));
    });
}

function concurrentTasks(tasks, maxConcurrent) {
    return new Promise((resolve, reject) => {
        const results = [];
        let completedCount = 0;
        const taskQueue = tasks.slice();
        const executeTask = () => {
            if (taskQueue.length === 0 && completedCount === tasks.length) {
                resolve(results);
                return;
            }
            while (taskQueue.length > 0 && results.filter(result => result.status === 'pending').length < maxConcurrent) {
                const task = taskQueue.shift();
                const taskPromise = asyncTask(task);
                taskPromise
                  .then(result => {
                        results.push({ task, status:'resolved', result });
                        completedCount++;
                        executeTask();
                    })
                  .catch(error => {
                        results.push({ task, status:'rejected', error });
                        completedCount++;
                        executeTask();
                    });
            }
        };
        executeTask();
    });
}

// 生成100个任务
const tasks = Array.from({ length: 100 }, (_, i) => i + 1);
concurrentTasks(tasks, 10)
  .then(results => {
        console.log('All tasks completed:', results);
    })
  .catch(error => {
        console.error('Overall error:', error);
    });
  1. 任务失败和错误恢复
    • 在每个任务的Promise中,使用catch块捕获任务执行过程中的错误,记录错误信息并将任务状态标记为rejected
    • 对于整体任务的执行,外层使用catch块捕获所有任务执行过程中可能出现的未处理错误,进行统一的错误处理,如记录日志、通知相关人员等。同时,即使某个任务失败,也不影响其他任务的继续执行,保证整体的并发控制逻辑正常进行。