Nestjs22之定时任务

1. 定时任务的类型

Nestjs中有三种任务类型:

  • addCronJob: 用于周期性任务,基于 Cron 表达式
  • addTimeout: 用于一次性延迟任务
  • addInterval: 基于固定的时间间隔而不是Cron表达式

在 NestJS 中,addCronJobaddTimeoutaddInterval 是三种不同的定时任务管理方法,下面介绍下他们的区别和使用场景。

2. 使用场景案例

2.1 addCronJob(基于 Cron 表达式的周期性任务)

2.1.1 功能

• 根据 Cron 表达式 按固定时间规则重复执行任务(如每天 8 点、每月的第 1 天)。 • 适合需要复杂时间调度的场景。

2.1.2 适用场景

  • 每天凌晨 3 点清理日志
  • 每周一上午 10 点发送周报
  • 每月最后一天生成账单
  • ...

2.1.3 代码示例

typescript 复制代码
import { SchedulerRegistry } from '@nestjs/schedule';
import { CronJob } from 'cron';

@Injectable()
export class CronService {
  constructor(private schedulerRegistry: SchedulerRegistry) {}

  // 添加 Cron 任务
  addDailyTask(jobName: string, cronExpression: string) {
    const job = new CronJob(cronExpression, () => {
      console.log('执行周期性任务');
    });

    this.schedulerRegistry.addCronJob(jobName, job);
    job.start();
  }

  // 删除 Cron 任务
  removeJob(jobName: string) {
    this.schedulerRegistry.deleteCronJob(jobName);
  }
}

2.2 addTimeout(一次性延迟任务)

2.2.1 功能

• 在指定延迟时间后 执行一次任务,之后自动销毁。 • 适合需要单次延迟触发的场景。

2.2.2 适用场景

• 用户下单后 30 分钟未支付自动取消订单。 • 5 秒后发送短信验证码。 • 10 分钟后提醒用户任务完成。

2.2.3 代码示例

typescript 复制代码
import { SchedulerRegistry } from '@nestjs/schedule';

@Injectable()
export class TimeoutService {
  constructor(private schedulerRegistry: SchedulerRegistry) {}

  // 添加延迟任务
  addDelayedTask(jobName: string, delayMs: number) {
    const timeout = setTimeout(() => {
      console.log('执行一次性任务');
    }, delayMs);

    this.schedulerRegistry.addTimeout(jobName, timeout);
  }

  // 取消任务
  cancelTask(jobName: string) {
    this.schedulerRegistry.deleteTimeout(jobName);
  }
}

2.3 addInterval(基于固定间隔的周期性任务)

2.3.1 功能

• 根据 固定时间间隔(如每隔 5 秒)重复执行任务。 • 适合需要简单周期性触发的场景。

2.3.2 适用场景

• 每隔 30 秒检查服务器状态。 • 每隔 10 分钟同步一次缓存数据。 • 每隔 1 小时刷新一次 API Token。

2.3.3 代码示例

typescript 复制代码
import { SchedulerRegistry } from '@nestjs/schedule';

@Injectable()
export class IntervalService {
  constructor(private schedulerRegistry: SchedulerRegistry) {}

  // 添加间隔任务
  addIntervalTask(jobName: string, intervalMs: number) {
    const interval = setInterval(() => {
      console.log('执行间隔任务');
    }, intervalMs);

    this.schedulerRegistry.addInterval(jobName, interval);
  }

  // 删除间隔任务
  removeInterval(jobName: string) {
    this.schedulerRegistry.deleteInterval(jobName);
  }
}

3. 总结

3.1 三者的核心区别对比

特性 addCronJob addTimeout addInterval
执行次数 周期性(按 Cron 表达式重复) 单次(延迟执行后销毁) 周期性(按固定间隔重复)
时间规则 Cron 表达式(如 0 3 * * * 延迟时间(如 30000 毫秒) 间隔时间(如 5000 毫秒)
任务管理 可手动启动/停止,需显式删除 执行后自动销毁,可提前取消 需显式删除以停止
底层实现 基于 node-cron 基于 Node.js 原生的 setTimeout 基于 Node.js 原生的 setInterval
适用场景 复杂时间规则(如每天、每周) 一次性延迟任务(如倒计时) 简单周期性任务(如轮询)
持久化支持 ❌ 任务重启后需重新注册 ❌ 任务重启后需重新注册 ❌ 任务重启后需重新注册
分布式系统兼容性 ❌ 单实例生效,多实例重复执行 ❌ 单实例生效,多实例重复执行 ❌ 单实例生效,多实例重复执行

3.2 如何选择?

  • 需要复杂时间规则addCronJob(如每天凌晨执行)。
  • 需要单次延迟任务addTimeout(如 30 分钟后取消订单)。
  • 需要简单重复任务addInterval(如每隔 5 秒检查状态)。
  • 需要分布式支持 → 改用 Bull + Redis 或数据库任务队列。

通过对比合理选择自己的使用场景,希望对大家有所帮助,如有错误,请指正O^O!

相关推荐
胡gh5 小时前
页面卡成PPT?重排重绘惹的祸!依旧性能优化
前端·javascript·面试
言兴5 小时前
# 深度解析 ECharts:从零到一构建企业级数据可视化看板
前端·javascript·面试
山有木兮木有枝_6 小时前
TailWind CSS
前端·css·postcss
烛阴6 小时前
TypeScript 的“读心术”:让类型在代码中“流动”起来
前端·javascript·typescript
杨荧6 小时前
基于Python的农作物病虫害防治网站 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python
Moment7 小时前
毕业一年了,分享一下我的四个开源项目!😊😊😊
前端·后端·开源
程序视点8 小时前
Escrcpy 3.0投屏控制软件使用教程:无线/有线连接+虚拟显示功能详解
前端·后端
silent_missile8 小时前
element-plus穿梭框transfer的调整
前端·javascript·vue.js
专注VB编程开发20年8 小时前
OpenXml、NPOI、EPPlus、Spire.Office组件对EXCEL ole对象附件的支持
前端·.net·excel·spire.office·npoi·openxml·spire.excel
古蓬莱掌管玉米的神8 小时前
coze娱乐ai换脸
前端