打包升级:node-cron原理详解
node-cron主要用来执行定时任务,它不仅提供cron语法,而且增加了NodeJS子进程执行和直接传入Date类型的功能。
一、前言
在理解node-cron之前,需要先知道它的基本用法,下面是一个在每分钟的第20秒到第50秒之间每隔4秒执行一次的定时任务:
const CronJob = require('../lib/cron.js').CronJob
const job = new CronJob('20-50/4 * * * * *', onTick)
job.start()
function onTick () {
const d = new Date()
console.log('tick: ', d)
}
接下来会从以下几个方面带你了解node-cron的原理:
- 部分注意事项
- cron格式的解析
- 使用setTiemout执行定时任务时的细节处理
- 如何计算cron格式下的时间间隔
二、注意事项
在正式进入源码的探索时,最好了解node-cron的基本用法以及相关参数的含义。
1、传参方式
node-cron提供CronJob函数创建定时任务,并且允许两种传参方式:
- 载荷形式:a, b, c
- 对象形式:{ a: a, b: b, c: c }
/**
* 为了节约篇幅,示例代码只展示主要内容
*/
function CronJob (cronTime, onTick, onComplete, startNow, timeZone, context, runOnInit, utcOffset, unrefTimeout) {
var _cronTime = cronTime;
var argCount = 0;
// 排除传入的参数是undefined的情况(要是我就直接argCount = arguments.length)
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] !== undefined) {
argCount++;
}
}
// 判断参数为对象类型的条件
if (typeof cronTime !== 'string' && argCount === 1) {
onTick = cronTime.onTick;
...
}
}
2、回调函数
node-cron中有两种回调函数:
- onTick: 每个时间节点触发的回调函数;
- onComplete: 定时任务执行完后的回调函数。
从CronJob函数中可以看到onTick回调函数是放在_callbacks中的,但是通过CronJob只能设置一个onTick函数,如果需要设置多个onTick函数,可以采用CronJob原型上的addCallback方法,并且这些onTick的执行顺序需要注意一下:
var fireOnTick = function () {
// 利用_callbacks数组模拟栈的行为 后进先出
for (var i = this._callbacks.length - 1; i >= 0; i--) {
this._callbacks[i].call(this.context, this.onComplete);
}
};
另外通过runOnInit参数决定onTick是否在定时任务初始化阶段执行一次:
if (runOnInit) {
this.lastExecution = new Date();
fireOnTick.call(this);
}
这两种回调函数都允许使用NodeJS子进程处理,举个例子:
// examples/basic.js
const CronJob = require('../lib/cron.js'