Course contentsShow
← Node.js
Lesson 272 of 1,9803. Asynchronous Patterns and Flow ControlFree lesson

Priority-Based Async Scheduling

You will create a scheduler that allows urgent tasks to jump ahead of background jobs in the work queue.

In this lesson, you will learn how to design an asynchronous scheduler that ensures urgent tasks jump to the front of the queue, effectively bypassing waiting background jobs.

The "Priority Lane" Problem

In a standard FIFO (First-In, First-Out) queue, a massive batch of background tasks—like generating reports or processing logs—can block high-priority work, such as a user’s authentication request or a real-time payment validation. To prevent this, we move away from a simple array and implement a Priority Queue.

Instead of one single line of tasks, think of your scheduler as having two distinct lanes: a high priority lane and a normal lane.

Implementing the Scheduler

We can manage this by using two separate arrays and a simple orchestration function. The scheduler always checks the high priority array first. Only when it is empty will it look at the normal array.

class PriorityScheduler {
  constructor() {
    this.highPriority = [];
    this.normalPriority = [];
  }

  enqueue(task, priority = 'normal') {
    if (priority === 'high') {
      this.highPriority.push(task);
    } else {
      this.normalPriority.push(task);
    }
    this.processNext();
  }

  async processNext() {
    // Always clear the high priority queue first
    const task = this.highPriority.shift() || this.normalPriority.shift();
    
    if (task) {
      await task();
      this.processNext();
    }
  }
}

Why this matters

By forcing the scheduler to shift() from highPriority before touching the normalPriority array, we create a non-blocking flow for critical tasks. Even if you have a thousand log-processing tasks waiting in the normal lane, the moment a high priority task arrives, the next execution cycle will pick it up immediately.

This approach prevents "queue starvation," where important work gets stuck behind lower-value background operations. It gives your Node.js application the intelligence to distinguish between "work that needs to be done" and "work that needs to be done now."

Key Takeaway: By separating your task queues based on urgency and prioritizing the processing of the high-priority queue, you ensure that critical asynchronous work is never delayed by lower-priority background jobs.