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!

相关推荐
Json_3 分钟前
使用vue2技术写了一个纯前端的静态网站商城-鲜花销售商城
前端·vue.js·html
1024熙3 分钟前
【Qt】——理解信号与槽,学会使用connect
前端·数据库·c++·qt5
少糖研究所4 分钟前
ColorThief库是如何实现图片取色的?
前端
冴羽5 分钟前
SvelteKit 最新中文文档教程(22)—— 最佳实践之无障碍与 SEO
前端·javascript·svelte
ZYLAB7 分钟前
我写了一个简易的 SEO 教程,希望能让新手朋友看完以后, SEO 能做到 80 分
前端·seo
小桥风满袖13 分钟前
Three.js-硬要自学系列4 (阵列立方体和相机适配、常见几何体、高光材质、lil-gui库)
前端·css
深海丧鱼14 分钟前
什么!只靠前端实现视频分片?
前端·音视频开发
ohMyGod_12317 分钟前
Vue如何实现样式隔离
前端·javascript·vue.js
涵信21 分钟前
第二十节:项目经验-描述一个React性能优化案例
前端·react.js·性能优化
Danny_FD26 分钟前
前端中的浮动、定位与布局
前端·css