Skip to content

定时任务

任务调度允许你安排任意代码(方法/函数)在固定日期/时间、重复间隔或在指定间隔后执行一次

安装

bash
$ pnpm add @nestjs/schedule
$ pnpm adad cron # cron 的版本要和 @nestjs/schedule 中使用的版本保持一致

接入

typescript
import { Module } from "@nestjs/common";
import { ScheduleModule } from "@nestjs/schedule";

@Module({
  imports: [ScheduleModule.forRoot()],
})
export class AppModule {}

组织定时任务模块和服务

typescript
@Module({
  providers: [TasksService],
  exports: [TasksService],
})
export class TasksModule {}
typescript
@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  constructor(private scheduleRegistry: SchedulerRegistry) {}

  @Cron(CronExpression.EVERY_30_SECONDS, {
    name: "30-SECONDS",
    timeZone: "Asia/Shanghai",
  })
  handleCron() {
    this.logger.debug("Called when the second is 30");
  }
}

定时任务装饰器

时间定义

在定时任务的执行函数前加上装饰器 @Cron():

Cron(cronTime: CronJobParams['cronTime'], options?: CronOptions)

这里定时任务的时间可以是:

  • 一次指定的日期和时间
  • 在指定的间隔内的指定时刻

标准定时模式:

  • 星号 (*)
  • 作用域 (1-3,5)
  • 步骤 (*/2)

corn 模式字符:

txt
* * * * * *
| | | | | |
| | | | | day of week
| | | | months
| | | day of month
| | hours
| minutes
seconds (optional)

@nestjs/schedule 提供了一个枚举:CronExpression, 方便进行定时任务

options

@cron 第二个参数是配置项,包含:

  • name 用于声明后访问和控制 cron-job
  • timeZone 指定执行时区,具体参考 链接

动态 cron job

可以在代码中任何位置注入:schedulerRegistry: SchedulerRegistry

动态关闭

假设已经有一个定时任务,name 为 notifications, 可以通过以下方式访问:

typescript
@Controller("task")
class TaskControll {
  constructor(private schedulerRegistry: SchedulerRegistry) {}

  @Get("stop")
  stopCron() {
    const job = this.schedulerRegistry.getCronJob("notifications");

    job.stop();
    console.log(job.lastDate());
  }
}

cron job 实例

getCronJob() 方法返回指定的 cron 作业。返回的 CronJob 对象有以下方法:

  • stop() - 停止计划运行的作业
  • start() - 重新启动已停止的作业
  • setTime(time: CronTime) - 停止作业,为其设置新时间,然后启动它
  • lastDate() - 返回上次执行作业发生的日期的 DateTime 表示形式
  • nextDate() - 返回 DateTime 表示的日期,表示计划下次执行作业的日期
  • nextDates(count: number) - 为将触发作业执行的下一组日期提供 DateTime 表示形式的数组(大小 count)。count 默认为 0,返回空数组。

动态开启

也可以在代码中动态开启一个定时任务:

typescript
@Controller("task")
class TaskControll {
  constructor(private schedulerRegistry: SchedulerRegistry) {}

  @Get("enable")
  enableCron(@Query("name") name: string, @Query("second") second: string) {
    const job = new CronJob(seconds, () => {
      this.logger.debug("Called when the second is 10");
    });

    this.scheduleRegistry.addCronJob(name, job);
    job.start();

    this.logger.debug(`job ${name} start`);
  }
}
2025( )
今日 29.17%
本周 57.14%
本月 32.26%
本年 52.33%
Powered by Snowinlu | Copyright © 2024- | MIT License