You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Node.js CLI应用中实现异步任务队列?解决bee-queue导致主进程冻结无法退出的问题

用bee-queue实现CLI提交任务后立即退出的方案

嘿,我之前也遇到过一模一样的问题!bee-queue完全能满足你的核心需求——关键是你得处理好队列的连接关闭,不然Node.js的事件循环会因为活跃的Redis连接一直挂着,导致CLI没法自动退出。

问题根源

bee-queue默认会和Redis保持持久连接,当你提交完任务后,如果不主动关闭这个连接,Node.js的事件循环会认为还有活跃的异步操作在运行,所以会一直卡住,不会终止CLI进程。

解决方案步骤

1. 提交任务后主动关闭队列连接

在你的CLI代码里,当所有任务都添加到队列后,一定要调用queue.close()来断开和Redis的连接,这样事件循环就会结束,CLI就能正常退出了。

举个完整的CLI示例代码:

const Queue = require('bee-queue');

// 初始化队列
const taskQueue = new Queue('background-tasks', {
  redis: {
    host: 'localhost', // 你的Redis地址
    port: 6379,
  },
});

// 批量添加任务的函数
async function enqueueTasks() {
  try {
    // 模拟添加多个任务
    const taskList = [
      { type: 'email', recipient: 'user1@example.com' },
      { type: 'report', data: 'monthly-sales' },
      { type: 'cleanup', target: 'temp-files' }
    ];

    for (const taskData of taskList) {
      await taskQueue.createJob(taskData).save();
      console.log(`✅ 任务已加入队列: ${taskData.type}`);
    }

    // 关键操作:添加完所有任务后关闭队列连接
    await taskQueue.close();
    console.log("\n🎉 CLI任务提交完成,即将退出");
  } catch (err) {
    console.error("❌ 提交任务失败:", err);
    // 出错时强制退出CLI
    process.exit(1);
  }
}

// 执行任务提交
enqueueTasks();

2. 确保Worker进程独立运行

要让队列任务在CLI退出后继续执行,你需要一个独立的Worker进程来处理队列任务——这个进程要长期运行,和CLI是分开的。

Worker示例代码(比如命名为task-worker.js):

const Queue = require('bee-queue');

const taskQueue = new Queue('background-tasks', {
  redis: {
    host: 'localhost',
    port: 6379,
  },
});

// 定义任务处理逻辑
taskQueue.process(async (job) => {
  console.log(`开始处理任务 [${job.id}]:${job.data.type}`);
  
  // 模拟任务耗时操作(比如发邮件、生成报告)
  await new Promise(resolve => setTimeout(resolve, 3000));
  
  console.log(`任务 [${job.id}] 处理完成`);
  return `Result for ${job.data.type}`;
});

console.log("🚀 任务Worker已启动,等待处理队列任务...");

运行流程

  1. 先启动Worker进程:node task-worker.js(这个进程会一直运行,监听队列)
  2. 运行你的CLI应用:node your-cli-app.js——提交完任务后,CLI会自动退出,而Worker会继续处理队列里的任务

额外注意事项

  • 如果是自己传入了自定义的Redis客户端实例给bee-queue,那除了调用queue.close(),还要记得手动关闭Redis客户端,避免连接泄漏。
  • 若需要确保任务至少执行一次,可以开启bee-queue的持久化配置,避免Redis重启后丢失任务。

这样就能完美实现你的需求:CLI提交任务后立即终止,后台任务由Worker继续执行~

内容的提问来源于stack exchange,提问作者Nicolas Llorca

火山引擎 最新活动