Understanding the Queue Data Structure in JavaScript (FIFO) — And Why a Linked List Implementation is Better
Photo by <a href="https://unsplash.com/@lisanto_?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Lisanto 李奕良</a> on <a href="ht

Understanding the Queue Data Structure in JavaScript (FIFO) — And Why a Linked List Implementation is Better

Introduction

Queues represent order, fairness, and predictable processing — the first item that enters is always the first one to exit (FIFO: First In, First Out). This pattern appears everywhere in computing, from server request handlers to asynchronous JavaScript event loops.

In this article, I break down:

  • What a queue is
  • Real-world web development use cases
  • Why array-based queues in JS can be inefficient
  • A full queue implementation using a Linked List (with O(1) enqueue and dequeue)


What Is a Queue?

A queue is a linear data structure where items are inserted at one end (back) and removed from the other (front).

It supports four fundamental operations:

  • enqueue(value) → Add to back
  • dequeue() → Remove from front
  • peek() → View front element
  • isEmpty() → Check emptiness


Real Use Cases in Web Development

  • Managing background tasks
  • Handling request queues
  • Job schedulers
  • Messaging queues
  • Print queues
  • Event processing

Whenever tasks must be processed in the order they arrive, a queue is the solution.


Queue Using an Array (Simple but Inefficient)

class Queue {
  constructor() {
    this.items = [];
  }

  enqueue(value) {
    this.items.push(value); // O(1)
  }

  dequeue() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items.shift(); // ❌ O(n)
  }

  peek() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items[0];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}
        

The .shift() method causes every element in the array to change index — this makes dequeue() O(n).

Not ideal for real queue workloads.


Queue Using a Linked List (Efficient — O(1) dequeue!)

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class Queue {
  constructor() {
    this.head = null;
    this.tail = null;
    this.size = 0;
  }

  enqueue(value) {
    const newNode = new Node(value);
    if (this.isEmpty()) {
      this.head = this.tail = newNode;
    } else {
      this.tail.next = newNode;
      this.tail = newNode;
    }
    this.size++;
  }

  dequeue() {
    if (this.isEmpty()) return undefined;

    const removed = this.head;
    this.head = this.head.next;
    if (!this.head) this.tail = null;
    this.size--;
    return removed.value;
  }

  peek() {
    return this.head?.value;
  }

  isEmpty() {
    return this.size === 0;
  }
}
        

With the linked list approach:

  • enqueue → O(1)
  • dequeue → O(1)
  • peek → O(1)

This matches the behaviour of a true queue perfectly.


Conclusion

Queues seem simple, but they are fundamental to how systems maintain order. Implementing them from scratch deepens understanding and builds stronger intuition for real-world architectures. Linked Lists provide the optimal performance characteristics for queue operations, making them the preferred approach.

You can find my complete implementation and examples on GitHub: https://github.com/Rezwan66/learning-lab/blob/main/dsa-practice/3_Class-Stack-Queue-Linked-List/practice/11_class_queue_linked_list.js

To view or add a comment, sign in

More articles by Shaikh Rezwan

Explore content categories