web-dev-qa-db-ja.com

node.jsのcronジョブ

Node.jsで1日の特定の時間に関数を定期的に呼び出す可能性はありますか?私の最初の実装は

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

ノードを再起動するたびに再起動するため、これは最適ではありません。これを実装するためのより良い可能性はありますか?

24
Thomas

再起動を防ぐには、永続的なデータ保存ジョブを作成する必要があります。

何かのようなもの :

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などに置き換えます。

21
Raynos

これは古い質問ですが、受け入れられた回答に加えて、例を含むライブラリについても言及する価値があります。

cron は、システムの時間のみを使用し、データベースの永続性を使用せずに、指定された関数を指定された間隔で実行する軽量パッケージです。

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
});

上記では、2つのファイルが必要であり、異なる間隔で設定された2つのcronジョブ内でそれらを呼び出します。ファイルは単に関数をエクスポートします:

//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")
};

ローカルで実行する場合でも、任意のリージョンのリモートサーバーで実行する場合でも、渡されたタイムゾーンに従って実行されます(ただし、これはオプションであり、分単位の場合は関係ありません)。

また、サーバー/スクリプトを再起動しても、システム時刻と同期されるため、その動作に影響はありません。 A "00 */5 * * * *"ジョブは5の倍数ごとに実行されます(5、10、15、20など)。したがって、スクリプトを24で再起動しても、29ではなく25で実行されます。

最後に、パッケージはcron構文を拡張して、左端に秒を含めました。したがって、ジョブを実行する正確な秒数を指定することもできます。

0
Talha Awan