Очереди задач в JavaScript для начинающих: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Зачем нужны очереди задач?

Представьте, что вы запускаете веб-сервер на Node.js. Пользователь отправляет запрос на отправку 1000 email-писем. Если обрабатывать этот запрос синхронно, сервер "зависнет" на несколько минут — все остальные пользователи не смогут получить ответ.

Как решить эту проблему? Ответ — очереди задач (task queues). Они позволяют отложить выполнение ресурсоёмких операций (отправка писем, генерация PDF, обработка изображений) и выполнять их в фоне, не блокируя основной поток приложения.

В этой статье мы разберём:

  • Что такое очередь задач и как она работает
  • Популярные библиотеки для Node.js (Bull, Kue)
  • Примеры кода: создание, добавление и обработка задач
  • Лучшие практики для начинающих

1. Основы очередей задач в Node.js

Что такое очередь задач?

Очередь задач — это структура данных, работающая по принципу FIFO (First In, First Out — первый пришёл, первый ушёл). Задачи добавляются в конец очереди, а обрабатываются из начала. Обычно очереди строятся на базе Redis — быстрого хранилища ключ-значение в памяти.

Основные компоненты очереди:

  • Producer — код, который добавляет задачи в очередь
  • Consumer (Worker) — код, который забирает задачи и выполняет их
  • Queue Manager — механизм, управляющий очередью (обычно Redis)

Популярные библиотеки

Для Node.js существуют две основные библиотеки:

  • Bull — современная, быстрая, с поддержкой приоритетов, повторов и задержек
  • Kue — старая, но простая библиотека (сейчас менее популярна)

В этой статье мы сосредоточимся на Bull, так как она активно поддерживается и имеет больше возможностей.

2. Установка и настройка Bull

Шаг 1: Установка Redis

Bull использует Redis. Если у вас нет Redis, установите его:

# macOS
brew install redis

# Ubuntu
sudo apt-get install redis-server

# Запуск Redis
redis-server

Шаг 2: Установка Bull

Создайте новый проект и установите пакет:

mkdir queue-demo
cd queue-demo
npm init -y
npm install bull

Шаг 3: Базовая настройка

Создайте файл queue.js:

const Queue = require('bull');

// Создаём очередь с именем 'emailQueue'
const emailQueue = new Queue('emailQueue', {
  redis: { host: '127.0.0.1', port: 6379 }
});

module.exports = emailQueue;

3. Пример: очередь для отправки email

Шаг 1: Создаём Producer (добавление задач)

Создайте файл producer.js:

const emailQueue = require('./queue');

async function addEmailTask(to, subject, body) {
  // Добавляем задачу в очередь
  const job = await emailQueue.add({
    to: to,
    subject: subject,
    body: body
  }, {
    // Опции задачи
    attempts: 3,          // Количество попыток при ошибке
    backoff: 5000,        // Задержка между попытками (5 сек)
    delay: 1000           // Задержка перед выполнением (1 сек)
  });

  console.log(`Задача добавлена с ID: ${job.id}`);
  return job;
}

// Пример использования
addEmailTask('user@example.com', 'Привет!', 'Тестовое сообщение');

Шаг 2: Создаём Worker (обработка задач)

Создайте файл worker.js:

const emailQueue = require('./queue');

// Функция, имитирующая отправку email
async function sendEmail(to, subject, body) {
  console.log(`Отправка письма на ${to}...`);
  // Имитация задержки
  await new Promise(resolve => setTimeout(resolve, 2000));
  console.log(`Письмо отправлено: ${subject}`);
}

// Обработчик очереди
emailQueue.process(async (job) => {
  const { to, subject, body } = job.data;
  
  console.log(`Обрабатываю задачу ${job.id}`);
  
  try {
    await sendEmail(to, subject, body);
    // Возвращаем результат (опционально)
    return { success: true, sentTo: to };
  } catch (error) {
    // Если ошибка — задача будет повторена (attempts: 3)
    throw new Error(`Ошибка отправки: ${error.message}`);
  }
});

console.log('Worker запущен и ожидает задачи...');

Шаг 3: Запуск

Запустите worker в одном терминале:

node worker.js

Затем в другом терминале запустите producer:

node producer.js

Вы увидите, как задача добавляется и сразу обрабатывается.

4. Расширенные возможности очередей

Приоритеты задач

Можно задать приоритет (чем меньше число, тем выше приоритет):

await emailQueue.add(data, { priority: 1 });  // Высокий приоритет
await emailQueue.add(data, { priority: 10 }); // Низкий приоритет

Повторные попытки и задержки

Bull автоматически повторяет задачи при ошибках. Настройки:

const job = await emailQueue.add(data, {
  attempts: 5,           // 5 попыток
  backoff: {
    type: 'exponential', // Экспоненциальная задержка
    delay: 2000          // 2, 4, 8, 16... секунд
  }
});

Обработка событий

Можно слушать события очереди:

emailQueue.on('completed', (job, result) => {
  console.log(`Задача ${job.id} завершена:`, result);
});

emailQueue.on('failed', (job, err) => {
  console.log(`Задача ${job.id} провалена:`, err.message);
});

Планирование задач (повторение)

Bull поддерживает повторяющиеся задачи (как cron):

// Добавляем задачу, которая будет выполняться каждый час
await emailQueue.add(data, {
  repeat                

Блоги

Рекомендаций по книгам