MST

星途 面试题库

面试题:JavaScript 闭包在并发异步任务中的应用

假设你正在使用 JavaScript 编写一个并发异步任务系统,要求在多个异步操作中利用闭包来管理共享状态,同时保证数据的一致性和正确性。请用代码示例展示如何实现,并解释你的设计思路。
27.8万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

代码示例

function asyncTaskSystem() {
    let sharedState = 0;
    const taskQueue = [];

    function addTask(task) {
        taskQueue.push(task);
    }

    function runTasks() {
        let currentIndex = 0;
        function executeNext() {
            if (currentIndex < taskQueue.length) {
                const task = taskQueue[currentIndex];
                currentIndex++;
                task(sharedState, (newState) => {
                    sharedState = newState;
                    executeNext();
                });
            }
        }
        executeNext();
    }

    return {
        addTask,
        runTasks
    };
}

// 使用示例
const system = asyncTaskSystem();
system.addTask((state, callback) => {
    setTimeout(() => {
        const newState = state + 1;
        console.log('Task 1 updated state:', newState);
        callback(newState);
    }, 1000);
});
system.addTask((state, callback) => {
    setTimeout(() => {
        const newState = state * 2;
        console.log('Task 2 updated state:', newState);
        callback(newState);
    }, 1500);
});
system.runTasks();

设计思路

  1. 闭包管理共享状态:在 asyncTaskSystem 函数内部定义了 sharedStatetaskQueue,这些变量被包含在 addTaskrunTasks 函数形成的闭包中。因此,addTaskrunTasks 可以访问和修改 sharedState,实现了共享状态的管理。
  2. 任务队列taskQueue 用于存储所有要执行的异步任务。addTask 函数负责将任务添加到队列中。
  3. 顺序执行任务runTasks 函数通过递归调用 executeNext 来顺序执行任务队列中的任务。每次执行一个任务时,任务会接收当前的 sharedState,并且在任务完成后通过回调函数更新 sharedState,从而保证数据的一致性和正确性。这样,每个任务都是基于前一个任务执行完毕后的状态进行操作,避免了并发操作可能导致的数据不一致问题。