队列是一种先进先出(FIFO)的数据结构,在前端异步编程中有重要应用。

队列 (Queue) 数据结构

队列是一种先进先出(FIFO - First In First Out)的数据结构,只能在队尾添加元素,在队首删除元素。

// 队列的核心操作

class Queue<T> {
  private items: T[] = [];

  enqueue(item: T): void   // 入队(队尾添加)
  dequeue(): T | undefined // 出队(队首移除)
  front(): T | undefined   // 查看队首
  isEmpty(): boolean       // 是否为空
  size(): number           // 队列大小
}

前端常见应用场景:

  • JavaScript 事件循环(宏任务队列、微任务队列)
  • 异步任务调度
  • 消息队列
  • 广度优先搜索 (BFS)
  • 打印任务队列
  • 请求限流队列

示例 1: 队列的基本操作

队首 →
空队列
← 队尾

队列大小: 0

是否为空:

对比栈: 栈是后进先出(LIFO),队列是先进先出(FIFO)。 就像排队买票,先来的先服务。

示例 2: 任务队列模拟

模拟任务队列的处理过程,任务按照先进先出的顺序执行。

等待队列 (0)
暂无任务
正在处理
空闲中
已完成 (0)
暂无完成

示例 3: JavaScript 事件循环

console.log('Start');

setTimeout(() => {
  console.log('Timeout');
}, 0);

Promise.resolve().then(() => {
  console.log('Promise');
});

console.log('End');
调用栈 (Call Stack)
微任务队列 (Microtask)
宏任务队列 (Macrotask)
执行日志
事件循环执行顺序:
  1. 执行同步代码(调用栈)
  2. 执行所有微任务(Promise.then, queueMicrotask)
  3. 执行一个宏任务(setTimeout, setInterval)
  4. 重复 2-3 步骤

示例 4: 循环队列

循环队列通过取模运算复用数组空间,避免了普通队列出队后空间浪费的问题。

-[0]
-[1]
-[2]
-[3]
-[4]
front: -1
rear: -1
队首 队尾 队首=队尾
class CircularQueue {
  constructor(k) {
    this.size = k;
    this.queue = new Array(k);
    this.front = -1;
    this.rear = -1;
  }

  enqueue(value) {
    if (this.isFull()) return false;
    if (this.isEmpty()) this.front = 0;
    this.rear = (this.rear + 1) % this.size;
    this.queue[this.rear] = value;
    return true;
  }

  dequeue() {
    if (this.isEmpty()) return false;
    if (this.front === this.rear) {
      this.front = -1;
      this.rear = -1;
    } else {
      this.front = (this.front + 1) % this.size;
    }
    return true;
  }
}