← Назад к вопросам

Куда добавляется и забирается элемент из очереди?

1.7 Middle🔥 122 комментариев
#JavaScript Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Очередь (Queue) в программировании: принцип FIFO

В классической структуре данных очередь (queue), работающей по принципу FIFO (First In, First Out — «первым пришёл, первым ушёл»), элементы добавляются и забираются с противоположных концов. Это аналогично очереди в реальной жизни: первый вставший в очередь будет первым обслужен.

Точки добавления и извлечения элементов

  • Элементы добавляются (enqueue) в конец очереди (rear/back/tail). Этот оператор часто называют enqueue, push или offer.
  • Элементы забираются (dequeue) из начала очереди (front/head). Этот оператор часто называют dequeue, shift или poll.

Это можно наглядно представить:

   Добавление (enqueue) -> [Элемент 3] [Элемент 2] [Элемент 1] -> Извлечение (dequeue)
                            (Конец очереди, rear)              (Начало очереди, front)

Порядок: Элемент 1 был добавлен первым, он же будет извлечён первым.

Реализация и примеры кода

На низком уровне очередь может быть реализована на основе массива или связного списка. В контексте Frontend-разработки мы чаще всего работаем с абстракциями очереди, предоставляемыми языком (JavaScript) или конкретными задачами.

1. Базовый пример на JavaScript (используя массив)

В JavaScript массивы (Array) имеют методы, позволяющие использовать их как очередь.

// Создаём пустую очередь
const queue = [];

// ENQUEUE: Добавляем элементы в КОНЕЦ (используем .push())
queue.push('Первый клиент');
queue.push('Второй клиент');
queue.push('Третий клиент');
console.log(queue); // ['Первый клиент', 'Второй клиент', 'Третий клиент']

// DEQUEUE: Забираем элемент из НАЧАЛА (используем .shift())
const servedClient = queue.shift();
console.log(servedClient); // 'Первый клиент'
console.log(queue); // ['Второй клиент', 'Третий клиент']

2. Более эффективная реализация (на основе связного списка)

Для частых операций dequeue использование array.shift() может быть неэффективным, так как он вызывает переиндексацию массива. Более оптимальную очередь можно создать, используя объекты и принцип связного списка.

class Queue {
    constructor() {
        this.items = {};
        this.frontIndex = 0;
        this.rearIndex = 0;
    }

    // Добавление в конец (enqueue)
    enqueue(element) {
        this.items[this.rearIndex] = element;
        this.rearIndex++;
    }

    // Извлечение из начала (dequeue)
    dequeue() {
        if (this.isEmpty()) return null;
        const item = this.items[this.frontIndex];
        delete this.items[this.frontIndex];
        this.frontIndex++;
        return item;
    }

    // Просмотр элемента в начале (peek)
    peek() {
        return this.items[this.frontIndex];
    }

    isEmpty() {
        return this.rearIndex - this.frontIndex === 0;
    }
}

// Использование
const taskQueue = new Queue();
taskQueue.enqueue('Загрузить данные');
taskQueue.enqueue('Обработать DOM');
taskQueue.enqueue('Отправить аналитику');

console.log(taskQueue.dequeue()); // 'Загрузить данные'
console.log(taskQueue.peek());    // 'Обработать DOM'

Практическое применение в Frontend

Понимание работы очереди критически важно в следующих сценариях:

  • Обработка задач или сообщений: Например, очередь на загрузку файлов, где файлы обрабатываются строго в порядке добавления.
  • Управление состоянием (например, Redux): В Redux действия (actions) обрабатываются редьюсером (reducer) строго в том порядке, в котором они были диспатчены, что по сути является очередью.
  • Асинхронные операции: Очередь микрозадач (microtasks) и макрозадач (macrotasks) в Event Loop JavaScript. Здесь задачи из очереди микрозадач (например, промисы) имеют приоритет и обрабатываются полностью перед взятием следующей задачи из очереди макрозадач (например, setTimeout).
  • Построение сложных алгоритмов: Обход дерева в ширину (Breadth-First Search, BFS) использует очередь для посещения узлов уровня за уровнем.
  • Буферизация ввода: Обработка пользовательского ввода (например, поисковых запросов) часто использует очередь для дебаунса (debounce) — система ждет паузу, а затем обрабатывает последний запрос из очереди.

Важные нюансы

  • Приоритетная очередь (Priority Queue): Это модификация, где элемент добавляется не строго в конец, а в соответствии со своим приоритетом. Извлекается же он всегда из начала (элемент с наивысшим приоритетом).
  • Дек (Deque — Double-Ended Queue): Это обобщение, где добавление и удаление возможны с обоих концов.
  • Круговая очередь (Circular Queue): Используется для эффективного использования памяти при реализации на массиве фиксированного размера.

Итог: В стандартной очереди добавление происходит строго в конец (rear), а извлечение — строго из начала (front). Эта простая, но мощная концепция лежит в основе управления порядком выполнения множества процессов как в низкоуровневых системах, так и в высокоуровневых фронтенд-приложениях, обеспечивая предсказуемость и контроль над потоком данных и задач.

Куда добавляется и забирается элемент из очереди? | PrepBro