Nodejs里用setTimeout去做定时任务?有点不太严谨了~

1,659 阅读5分钟

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。

背景

前几天接手了一个老项目,并且有了一个奇葩新需求,具体是这样的:数据库那边需要维护一张状态表,这个状态表是需要尽量实时去变化的。

按理说这个操作应该是数据库那边自己去设置定时器去完成才对,但是负责人说数据库那边太落后,做不了,看能不能在 nodejs 这一层来做,我就答应了下来,但是我其实也没做过这么奇怪的要求。

image.png

定时器?setTimeout?

由于我没在 nodejs 这一层做过定时器,所以我第一想到的就是 setTimeout

// 间隔5分钟
const TIME = 5 * 60 * 1000
// 更新数据表函数
const update = () => {...}
setTimeout(() => {
    update()
}, TIME)

但是这样做肯定是不对的,有几个缺点

  • 做不到卡点执行,比如我想1:05-1:10-1:15这样固定间隔卡点去执行
  • nodejs 代码一更新,这个定时器就重新执行了,又重新计时了
  • 需要手动设置时间区域,比如我只想0-10点执行

cron

于是在同事的推荐下,我使用了 cron 这个库,在 Node.js 中使用 cron 库可以轻松地创建定时任务。cron 是一个基于时间的任务调度器,可以让你按照特定的时间表达式运行任务

使用方法

  1. 首先需要安装这个库
npm install cron
  1. 引入cron模块:
    在你的Node.js脚本中引入cron模块:
const cron = require('cron');
  1. 创建定时任务:
    通过使用cron.CronJob类,你可以创建一个定时任务,指定任务的定时规则。
const job = new cron.CronJob('* * * * *', () => {
  // 在这里定义要运行的任务逻辑
  console.log('This job runs every minute!');
});

上面的示例中,* * * * *是Cron时间表达式,它指定了任务运行的时间规则,每分钟运行一次。

  1. 启动定时任务:
    使用job.start()方法启动定时任务。
job.start();

完成上述步骤后,你的定时任务将开始运行,并按照你指定的时间规则执行任务逻辑。

以下是一个完整的示例,每天的上午10点运行一次任务:

const cron = require('cron');

const job = new cron.CronJob('0 10 * * *', () => {
  // 在这里定义要运行的任务逻辑
  console.log('This job runs every day at 10 AM!');
});

job.start();

在上面的示例中,0 10 * * *表示任务将在每天的上午10点运行。

你可以根据自己的需求和任务的时间规则进行配置,cron库支持几乎所有常见的Cron时间表达式。

Cron 时间表达式

Cron时间表达式是用来指定定时任务执行时间的字符串表达式,它由空格分隔的多个时间字段组成。Cron时间表达式的规则如下:

* * * * * *
| | | | | |
| | | | | +-- 年份 (1970 - 2099)
| | | | +---- 星期 (0 - 7) (星期天为07)
| | | +------ 月份 (1 - 12)
| | +-------- 日 (1 - 31)
| +---------- 小时 (0 - 23)
+------------ 分钟 (0 - 59)

每个时间字段都有一组允许的值和特殊字符:

  • 分钟字段 (0 - 59):

    • 可接受的数值范围是0到59。
  • 小时字段 (0 - 23):

    • 可接受的数值范围是0到23。
  • 日字段 (1 - 31):

    • 可接受的数值范围是1到31。
  • 月字段 (1 - 12):

    • 可接受的数值范围是1到12。
  • 星期字段 (0 - 7):

    • 可接受的数值范围是0到7,其中0和7都表示星期天。
  • 年字段 (1970 - 2099):

    • 可接受的数值范围是1970到2099。

在每个时间字段中,你可以使用以下特殊字符:

  • 星号 (*):

    • 表示匹配该字段的所有值。例如,*在分钟字段中表示匹配0到59之间的所有值。
  • 逗号 (,):

    • 用逗号分隔多个值。例如,1,3,5在月字段中表示1月、3月和5月。
  • 斜线 (/):

    • 用来指定一个范围的值和一个增量步长。例如,0-30/5在分钟字段中表示0到30之间每5分钟执行一次任务。
  • 减号 (-):

    • 用来指定一个范围的值。例如,1-5在日字段中表示1到5号。
  • 问号 (?):

    • 用于指示该字段的值没有具体要求,可以匹配任何值。通常在日期和星期字段中使用。

经典的Cron时间表达式示例:

  • 每分钟执行一次:* * * * *
  • 每天的上午10点执行一次:0 10 * * *
  • 每周的星期日的中午12点执行一次:0 12 * * 0
  • 每月的1号上午9点30分执行一次:30 9 1 * *
  • 每年的1月1日凌晨1点执行一次:0 1 1 1 *

结语 & 加学习群 & 摸鱼群

我是林三心

  • 一个待过小型toG型外包公司、大型外包公司、小公司、潜力型创业公司、大公司的作死型前端选手;
  • 一个偏前端的全干工程师;
  • 一个不正经的掘金作者;
  • 一个逗比的B站up主;
  • 一个不帅的小红书博主;
  • 一个喜欢打铁的篮球菜鸟;
  • 一个喜欢历史的乏味少年;
  • 一个喜欢rap的五音不全弱鸡

如果你想一起学习前端,一起摸鱼,一起研究简历优化,一起研究面试进步,一起交流历史音乐篮球rap,可以来俺的摸鱼学习群哈哈,点这个,有7000多名前端小伙伴在等着一起学习哦 --> 摸鱼沸点

image.png