Cronjobs в node.js

Есть ли возможность периодически вызывать функции в определенное время дня в node.js? Моя первая реализация была

setInterval(functionName(),(24*60*60*1000));

Это субоптимально, потому что он будет перезагружаться при каждом перезапуске node. Есть ли лучшие возможности для реализации этого?

Ответ 1

Чтобы защитить от перезапусков, вам нужно создать хранимое задание с сохраненными данными.

Что-то вроде:

Job = {
    _id: Number,
    job: String,
    dueDate: Date,
    completed: Boolean
}

Затем введите код следующим образом:

var createJob = function(url, date) {
    var j = db.create(Job, function(j) {
         j.job = url;
         j.dueDate = date;
         j.save();
    });
};

var runJob = function(j) {
    var id = j._id;
    setInterval(j.dueDate - Date.now(), function() {
         db.getOne(Job, { _id : id }, function(j) {
             require(j.job);
             j.finished = true;
             j.save();  
         });
    });
    j = null;
};

При запуске вам просто нужно сделать что-то вроде:

db.get(Job, { finished: false }, function(jobs) {
    jobs.forEach(runJob);
});

Замените общий db на MongoDB, CouchDB, Redis и т.д.

Ответ 2

Это старый вопрос, но в дополнение к принятому ответу стоит упомянуть библиотеку с примерами.

cron - это легкий пакет, который выполняет заданную функцию с заданным интервалом, используя только системное время и постоянство db.

const CronJob = require('cron').CronJob;
const jobFiveMinutes = require("./job.five-minutes");
const jobMondayMorning = require("./job.monday-morning");

var jobs = [
    new CronJob({
        cronTime: "00 */5 * * * *", //every five minutes
        onTick: function() {
            jobFiveMinutes();
        },
        start: false, //don't start immediately
        timeZone: 'America/Los_Angeles'
    }),
    new CronJob({
        cronTime: "00 00 9 * * 1", //9 am Monday morning
        onTick: function() {
            jobMondayMorning();
        },
        start: false,
        timeZone: 'America/Los_Angeles'
    }),
];

jobs.forEach(function(job) {
    job.start(); //start the jobs
});

Выше мы потребовали два файла и назовите их внутри двух cronjobs, установленных с разными интервалами. Файлы просто экспортируют функции:

//job.five-minutes.js
module.exports = function(){
    console.log("runs every five minutes")
};

//job.monday-morning.js
module.exports = function(){
    console.log("runs every monday morning at 9 am, Los Angeles time")
};

Запускаете ли вы его локально или на удаленном сервере в любом регионе, он будет работать в соответствии с пройденным часовым поясом (что необязательно, и не имеет значения в случае минут).

Кроме того, перезапуск сервера / script не повлияет на его работу при синхронизации с системным временем. Задача "00 */5 * * * *" будет выполняться на каждом кратном 5, то есть 5, 10, 15, 20 и так далее. Таким образом, даже если вы перезапустите script на 24, он будет работать с 25 не 29.

Наконец, пакет расширил синтаксис cron, включив секунды слева. Поэтому вы можете даже сказать, в какой именно момент минуты вы хотите запустить задание.