Skip to content

Nest 定时任务

前置

安装依赖

ts
pnpm install --save @nestjs/schedule

创建定时任务模块和 services

ts
nest g module task
nest g service task

app.module.ts 中引入定时任务模块

ts
// 定时任务模块
import { TaskModule } from './modules/task/task.module';
import { ScheduleModule } from '@nestjs/schedule';
@Module({
  imports: [
    // 定时任务引入包
    ScheduleModule.forRoot(),
    // 定时任务模块
    TaskModule,
  ],
  controllers: [],
  providers: [],
})

使用

  • task.service.ts

每隔 1 分钟 走一个定时任务 和 每隔十秒走一个定时任务

ts
import { Injectable } from "@nestjs/common";
import { Cron, CronExpression } from "@nestjs/schedule";

@Injectable()
export class TaskService {
  // 第一个定时任务,每1分钟执行一次
  @Cron("* * * * *", { name: "task2", timeZone: "Asia/Shanghai" })
  handleEvery5Seconds() {
    console.log("Every 1 minute task executed");
  }

  // 第二个定时任务,每10秒执行一次
  @Cron(CronExpression.EVERY_10_SECONDS)
  handleEvery10Seconds() {
    console.log("Every 10 seconds task executed");
  }
}

参数说明

  • @Cron 装饰器接受一个字符串或 CronExpression 枚举值作为参数,用于指定任务的执行时间。

枚举值如下图

字符串设置

规则

其中年是可选的,所以一般都是 6 个。 每个字段都可以写 *,比如秒写 * 就代表每秒都会触发,日期写 * 就代表每天都会触发。

如果不知道星期就直接写?代表忽略星期

- 代表范围

ts
0 20-30 * * * *

这个表达式就是从 20 到 30 的每分钟每个第 0 秒都会执行任务。

, 代表分割

ts
0 5,10 * * * *

这个表达式就是每小时的第 5 和 第 10 分钟的第 0 秒执行定时任务:

/ 代表间隔

ts
0 5/10 * * * *

这个表达式就是从第 5 分钟开始,每隔 10 分钟触发一次:

举例

  • 每分钟的第一秒执行一次
ts
* * * * *
  • 每小时执行一次

这个表达式会在每小时的第 0 分钟执行任务。

ts
0 * * * *
  • 每天执行一次

这个表达式会在每天的午夜 00:00 执行任务。

ts

0 0 * * *
  • 每天特定时间执行

这个表达式会在每天的上午 8:00 执行任务。

ts
0 8 * * *
  • 每周一次
ts
0 0 * * 1
  • 每周一次
ts
0 0 1 * *
  • 每年一次
ts
0 0 1 1 *
  • 每小时的第 15 分钟执行

这个表达式会在每小时的第 15 分钟执行任务。

ts
0 15 * * * *
  • 每天的上午 9 点到下午 5 点,每小时执行一次

这个表达式会在每天的上午 9 点到下午 5 点之间,每小时的开始执行任务。

ts
0 0 9-17 * * *
  • 每周一到周五 每天上午 8 点执行

这个表达式会在每周的工作日(周一至周五)的上午 8:00 执行任务。

ts
0 0 8 * * 1-5
  • 每天凌晨 1 点执行一次
ts
0 1 * * *
  • 每周一凌晨 1 点执行一次
ts
0 1 * * 1
  • 每周一到周五凌晨 1 点执行一次
ts
0 1 * * 1-5

还可以设置时区

  • 增加第二个参数 可以设置 name 和指定的时区
ts
import { Inject, Injectable } from "@nestjs/common";
import { Cron, CronExpression } from "@nestjs/schedule";
// 数据库
import { PrismadbService } from "../prisma/prisma.service";
@Injectable()
export class TaskService {
  @Inject()
  private prismadbService: PrismadbService;
  // 第一个定时任务,每分钟执行一次
  @Cron("* * * * *", { name: "task1", timeZone: "Asia/Shanghai" })
  async handleEveryOneMinute() {
    const result = await this.prismadbService.student.findMany({});
    console.log(result);
  }

  // 第二个定时任务,每10秒执行一次
  @Cron(CronExpression.EVERY_10_SECONDS)
  handleEvery10Seconds() {
    console.log("Every 10 seconds task executed");
  }
}

管理查看所有的定时任务

  • app.module.ts 修改
ts
import { Inject, Module, OnApplicationBootstrap } from "@nestjs/common";
// 定时任务模块
import { TaskModule } from "./modules/task/task.module";
import { ScheduleModule, SchedulerRegistry } from "@nestjs/schedule";
@Module({
  imports: [
    // 定时任务模块
    ScheduleModule.forRoot(),
    TaskModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule implements OnApplicationBootstrap {
  @Inject(SchedulerRegistry)
  private schedulerRegistry: SchedulerRegistry;
  onApplicationBootstrap() {
    const jobs = this.schedulerRegistry.getCronJobs();
    console.log(jobs);
  }
}