2011-04-12 18 views
24

¿Existe la posibilidad de llamar periódicamente funciones en un momento específico del día en node.js? Mi primera implementación fueCronjobs en node.js

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

Esto no es óptimo, ya que se reiniciará cada vez que reinicie el nodo. ¿Hay mejores posibilidades para implementar esto?

+7

Utilice [node-cron] (https://github.com/ncb000gt/node-cron). –

+3

@MathiasBynens ¿Cómo es [node-cron] (https://github.com/ncb000gt/node-cron) resistente a reinicios? Lo siento, por ser un nigromante, pero esta Q sigue siendo una de las primeras en los resultados de Google. Tenga en cuenta que 'node-cron' NO se basa en crontables. – meeDamian

+0

@meeDamian node-cron ejecuta sobre todo scripts en intervalos, por lo que comenzarán a ciclar nuevamente al reiniciar. También hay una opción para ejecutar un trabajo una vez [por fecha] (https://www.npmjs.com/package/cron#another-example-with-date), este es un valor que presumiblemente proviene de datos persistentes fuente. – igneosaur

Respuesta

21

Para evitar reinicios, debe crear un trabajo almacenado de datos persistentes.

Algo así como:

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

Luego tienen algún código como sigue:

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

En la puesta en marcha sólo hay que hacer algo como:

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

Sustituir el genérica db con MongoDB, CouchDB, Redis, etc.

+0

Supongamos que se están ejecutando varios trabajos cron. ¿Hay alguna forma de simplemente eliminar uno de ellos? Debido a que encontré un escenario, necesitaba matar un trabajo e hice otro mantenimiento, pero aún quería que se ejecutaran otros trabajos. ¡Gracias! – zsong

0

Es una vieja pregunta, pero además de la respuesta aceptada, vale la pena mencionar una biblioteca con ejemplos.

cron es un paquete liviano que ejecuta la función especificada a intervalos determinados, utilizando solo el tiempo del sistema y la persistencia no de 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 
}); 

Arriba, solicitamos dos archivos y los llamamos dentro de dos cronjobs, configurados a intervalos diferentes. Los archivos simplemente exportar las funciones:

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

Si lo ejecuta de forma local o en el servidor remoto en cualquier región, se ejecutará de acuerdo con la zona horaria pasado (que es opcional, sin embargo, y no importa en el caso de minutos) .

Además, reiniciar el servidor/script no afectará su funcionamiento, ya que se sincroniza con la hora del sistema. Se ejecutará una tarea "00 */5 * * * *" en cada múltiplo de 5, es decir, 5, 10, 15, 20, etc. Entonces, incluso si reinicia el script a 24, se ejecutará a 25 no 29.

Por último, el paquete ha extendido la sintaxis cron para incluir segundos a la izquierda. Por lo tanto, incluso puede decir en qué segundo exacto del minuto desea ejecutar el trabajo.