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!

相关推荐
雪芽蓝域zzs2 分钟前
第三十五节:Axios 统一错误拦截、401 Token 过期处理
前端·javascript·vue.js
XIE3928 分钟前
TipKit:开源富文本编辑器套件,一套逻辑,任意风格!
前端·笔记·开源
范什么特西22 分钟前
一些常用名词
开发语言·前端·javascript
晴天1623 分钟前
前端打包工具全景解析
前端
晴天1625 分钟前
Vite vs Webpack 全方位对比
前端·webpack·node.js
体毛旺盛的猿27 分钟前
HarmonyOS开发面试题
前端·华为·harmonyos
anOnion42 分钟前
构建无障碍组件之Landmarks Pattern
前端·html·交互设计
牧瀬クリスだ43 分钟前
前端三件套基础之JS!!!!
前端·javascript
风骏时光牛马1 小时前
提示词工程:大模型交互的核心塑造技术
前端
单线程_011 小时前
从案例分析 Vue3 Tokenizer+Parser 源码四
前端·javascript·vue.js