JavaScript (Node.js) 任务队列:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

在 JavaScript (Node.js) 中处理任务队列



在现代 Web 应用和微服务架构中,经常需要执行不应阻塞主执行线程的后台任务。任务队列是一种强大的工具,有助于管理异步操作,确保可靠性、可扩展性和容错性。本文将详细介绍如何在 Node.js 环境中处理任务队列,探讨主要库并编写实用的代码示例。



什么是任务队列,为什么需要它?



任务队列 (Task Queue) 是一种按 FIFO(先进先出)原则工作的数据结构。任务被放入队列,并由工作进程 (worker) 按到达顺序处理。主要使用场景包括:



  • 发送电子邮件通知 — 无需让用户等待邮件发送完成。
  • 生成报告或 PDF — 资源密集型操作,最好异步执行。
  • 处理上传的图片 — 调整大小、压缩、添加水印。
  • 与外部 API 集成 — 执行带频率限制 (rate limiting) 的请求。
  • 计划任务 (cron) — 定期清理数据库或更新缓存。


使用队列可以减轻主服务器负担,提高容错性(如果某个工作进程崩溃,任务将传递给另一个),并确保即使在临时故障时也能执行任务。



Node.js 中的简单内存队列



首先,我们实现一个没有外部依赖的最简单队列。这种方法适用于原型设计或非常小的项目,但由于缺乏持久性,不建议用于生产环境。



class SimpleQueue {    constructor() {        this.queue = [];        this.processing = false;    }

enqueue(task) { this.queue.push(task); this.processNext(); }

async processNext() { if (this.processing || this.queue.length === 0) return; this.processing = true; const task = this.queue.shift(); try { await task(); } catch (err) { console.error('任务执行错误:', err); } finally { this.processing = false; this.processNext(); } }}

// 使用示例const queue = new SimpleQueue();

queue.enqueue(async () => { console.log('任务 1: 发送电子邮件');});

queue.enqueue(async () => { console.log('任务 2: 生成报告');});

console.log('任务已添加到队列');


这段代码演示了基本机制:任务按顺序逐个执行。但是,如果服务器重启,所有未处理的任务都将丢失。



Bull — 基于 Redis 的专业队列



对于 Node.js 中的严肃项目,事实上的标准是 Bull 库。它使用 Redis 作为后端,提供持久性、优先级支持、重试机制和延迟任务。



安装:

npm install bull


简单的生产者和消费者示例:



const Queue = require('bull');

// 创建一个名为 'email-queue' 的队列const emailQueue = new Queue('email-queue', { redis: { host: 'localhost', port: 6379 }});

// 工作进程函数:处理任务emailQueue.process(async (job) => { const { to, subject, body } = job.data; console.log(`发送邮件至 ${to}: ${subject}`); // 这里应该是实际的邮件发送代码 await new Promise(resolve => setTimeout(resolve, 1000)); return { success: true };});

// 添加任

博客

书籍推荐