You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持任务推送与并发控制的JavaScript异步任务运行器?

Concurrent Task Runner with Async Support

Got it, let's build this robust task runner that handles concurrent execution limits and supports async tasks like user input waits or API calls. Here's a complete implementation with clear explanations:

Full Implementation Code

class Runner {
  constructor(concurrent) {
    this.taskQueue = [];
    this.currentRunning = 0;
    this.concurrentLimit = concurrent;
  }

  push(task) {
    // Add the new task to our waiting queue
    this.taskQueue.push(task);
    // Immediately try to start the next available task
    this._runNext();
  }

  async _runNext() {
    // Keep processing tasks as long as we have slots and waiting tasks
    while (this.currentRunning < this.concurrentLimit && this.taskQueue.length > 0) {
      const task = this.taskQueue.shift();
      this.currentRunning++;

      try {
        // Wait for the async task to complete (works for promises, async functions)
        await task();
      } catch (error) {
        // Optional: Handle task failures here, or let the task itself manage errors
        console.error(`Task failed:`, error);
      } finally {
        // Free up a slot once the task finishes (success or failure)
        this.currentRunning--;
        // Trigger the next task in the queue
        this._runNext();
      }
    }
  }
}

Key Details Explained

  • Concurrent Limit Enforcement: We track currentRunning to make sure we never exceed the specified number of active tasks at any time.
  • Queue Management: New tasks are added to taskQueue when pushed, and the private _runNext method handles dequeuing and executing tasks as slots open up.
  • Async Task Compatibility: Using await task() ensures we properly wait for all types of async operations—whether it's an API call, a setTimeout, or a promise waiting for user input.
  • Error Resilience: The try/catch block ensures a failed task won't crash the entire runner; we log the error (or handle it as needed) and keep processing the queue.

Example Usage

Let's test it with simulated async tasks to see how the concurrency works:

// Create a runner that allows 2 concurrent tasks
const runner = new Runner(2);

// Helper to create mock async tasks (mimics API calls or user actions)
const createMockTask = (taskId, delay) => {
  return async () => {
    console.log(`Starting task ${taskId}`);
    await new Promise(resolve => setTimeout(resolve, delay));
    console.log(`Finished task ${taskId}`);
  };
};

// Push tasks to the runner
runner.push(createMockTask(1, 2000));
runner.push(createMockTask(2, 1000));
runner.push(createMockTask(3, 1500));
runner.push(createMockTask(4, 500));

In this test, tasks 1 and 2 start right away. When task 2 finishes after 1 second, task 3 kicks off immediately. Task 4 waits until either task 1 or 3 completes before starting—all while sticking to the 2-task concurrent limit.

内容的提问来源于stack exchange,提问作者Roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:40:00