Очереди задач для TypeScript: Bull, Bee-Queue и асинхронная обработка

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

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

Начать курс

Очереди задач для TypeScript: полное руководство по Bull и Bee-Queue

При разработке современных веб-приложений на TypeScript часто возникает необходимость выполнять длительные или ресурсоёмкие операции асинхронно, не блокируя основной поток. Например: отправка email-уведомлений, генерация PDF-отчётов, обработка изображений или синхронизация с внешними API. Для решения этих задач используются очереди задач (job queues). В этой статье мы подробно рассмотрим две самые популярные библиотеки для TypeScript — Bull и Bee-Queue, а также разберём, как интегрировать их в ваш проект.

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

Очередь задач позволяет:

  • Разделить ответственность — основной сервис отвечает только за постановку задачи, а обработчик — за её выполнение.
  • Управлять нагрузкой — можно ограничить количество параллельных задач (concurrency).
  • Гарантировать доставку — задачи не теряются даже при падении процесса (благодаря Redis).
  • Планировать выполнение — отложить задачу на определённое время или повторять её по расписанию.
  • Обрабатывать ошибки — автоматические повторные попытки (retry) с экспоненциальной задержкой.

Bull — самая популярная очередь для Node.js и TypeScript

Bull — это мощная библиотека на основе Redis, поддерживающая полный набор функций: приоритеты, повторные попытки, задержки, паузы, события и мониторинг. Bull имеет отличную типизацию для TypeScript.

Установка и настройка

npm install bull @types/bull

Простой пример очереди для отправки email:

import Queue from 'bull';

interface EmailJob {
  to: string;
  subject: string;
  body: string;
}

// Создаём очередь с именем 'email'
const emailQueue = new Queue<EmailJob>('email', {
  redis: { host: 'localhost', port: 6379 },
  defaultJobOptions: {
    attempts: 3,          // до 3 попыток
    backoff: { type: 'exponential', delay: 2000 },
    removeOnComplete: true,
  }
});

// Обработчик — выполняется в фоне
emailQueue.process(async (job) => {
  console.log(`Отправка email на ${job.data.to}`);
  // Имитация отправки
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log(`Email отправлен: ${job.data.subject}`);
});

// Добавляем задачу
async function addEmail() {
  await emailQueue.add({
    to: 'user@example.com',
    subject: 'Привет из очереди!',
    body: 'Это тестовое письмо.',
  });
}

addEmail();

Продвинутые возможности Bull

  • Повторяющиеся задачи (cron): queue.add(data, { repeat: { cron: '0 8 * * *' } })
  • Приоритеты: queue.add(data, { priority: 1 }) — чем меньше число, тем выше приоритет.
  • Задержка выполнения: queue.add(data, { delay: 60000 }) — отложить на 1 минуту.
  • События: можно подписаться на completed, failed, progress и другие.
  • Пауза/возобновление: queue.pause() / queue.resume().
// Обработка событий
emailQueue.on('completed', (job, result) => {
  console.log(`Задача ${job.id} завершена`);
});

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

Bee-Queue — лёгкая альтернатива

Bee-Queue — это минималистичная очередь на Redis, которая проще и быстрее Bull в плане потребления памяти. Подходит для небольших проектов или случаев, когда не нужны сложные настройки.

Установка и пример

npm install bee-queue
import Bee from 'bee-queue';

interface ImageJob {
  imageId: string;
  format: 'png' | 'jpg';
}

const imageQueue = new Bee<ImageJob>('image-processing', {
  redis: { host: 'localhost', port: 6379 },
  isWorker: true,
  removeOnSuccess: true,
});

// Обработчик
imageQueue.process(async (job) => {
  console.log(`Обработка изображения ${job.data.imageId} в формат ${job.data.format}`);
  // Имитация обработки
  await new Promise(resolve => setTimeout(resolve, 2000));                    

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