【问题标题】:Scheduling Tasks in Node.js Using Timers instead of Scheduled Cron Jobs在 Node.js 中使用计时器而不是计划的 Cron 作业来计划任务
【发布时间】:2017-06-16 08:48:06
【问题描述】:

这是我的目标:

最后一次文档更新5分钟后,我要执行一次性任务

所以这就是动作流的样子:

  1. 用户更新文档 - 计时器已启动并从 5 分钟开始倒计时
  2. 如果用户再次更新同一个文档并且之前的计时器(由 document._id 标识)仍在运行,则将该计时器重置为 5 分钟并重复倒计时
  3. 当计时器到时 - 执行一次任务

我以前没有做过这样的事情,我不知道从哪里开始。

我可以使用 Mongoose 中可用的方法轻松挂钩文档更改(即在保存时,执行 func 以设置或重置计时器)

但是,我想不出办法:

  • 创建一个等待 5 分钟的计时器 - 然后执行一个任务
  • 使计时器可访问,以便我可以重置计时器
  • 使计时器可访问,以便我可以添加额外的变量,这些变量将在计时器结束时在函数中使用

我调查了 Cron 作业,但它们似乎是每天在同一时间安排的任务。

我需要一个可以延迟任务的计时器,还需要能够重置该计时器,并向计时器添加额外数据。

任何提示表示赞赏。

【问题讨论】:

    标签: node.js timer cron


    【解决方案1】:

    这是我设法完成的解决方案。

    首先,值得注意的是,我最初的假设是正确的:

    Cron 作业非常适合每天在同一时间安排的重复性任务。但是,对于动态创建并具有倒计时元素的任务,cron 作业不是正确的工具。

    但是,输入 node-schedule (https://www.npmjs.com/package/node-schedule)

    Node Schedule 是用于 Node.js 的灵活的类似 cron 和不类似 cron 的作业调度程序。它允许您安排作业(任意函数)以在特定日期执行,并带有可选的重复规则。 它在任何给定时间只使用一个计时器(而不是每秒/分钟重新评估即将到来的工作)

    计时器的使用确实是这些即时任务所需要的。

    所以我的解决方案如下所示:

    var schedule = require('node-schedule'),
    email_scheduler = {};
    
    email_scheduler["H1e5nE2GW"] = schedule.scheduleJob(Date.now() + 10000, function(){
      console.log('its been a total of 10 seconds since initalization / reset.');
    });
    
    var second_attempt = schedule.scheduleJob(Date.now() + 5000, function(){
      console.log("5 seconds elapsed from start, time to reset original scheduled job");
    
      email_scheduler["H1e5nE2GW"].cancel();
    
      email_scheduler["H1e5nE2GW"] = schedule.scheduleJob(Date.now() + 10000, function(){
        console.log('its been a total of 10 since last one seconds.');
      });
    
      schedule.scheduleJob(Date.now() + 5000, function(){
        console.log("it's been another 5 seconds since reset");
    
      });
    });
    

    我的想法(虽然尚未测试)是我可以通过创建节点模块来为 email_scheduler 对象创建一个类似单例的实例。像这样:

    // node_modules/email-scheduler/index.js
    
    module.exports = {};
    

    这样,我可以访问 scheduleJobs 并在节点应用程序的每个文件中重置计时器。

    【讨论】:

    • 如果我将调度程序存储在 mongodb 中而不是内存中会有所不同吗?
    • 我认为调度程序本身必须在内存中。但是每个调度器操作中使用的数据可以存储在 MongoDB 中并加载到调度器函数中。
    • 我不知道该怎么做.. 你能详细说明一下吗
    • 为什么不喜欢这个例子呢?为什么要从 mongodb 加载?
    • 实际上我希望时间表在服务器重新启动时保持不变,因此 mongoDB
    【解决方案2】:

    您可以为此使用事件。用一些参数调用一个事件,在你的任务之前添加睡眠并执行你的任务。但是在 nodejs 中添加 sleep 或 settimeout 并不是一个好主意。

    【讨论】:

      【解决方案3】:

      我也有同样的困惑,但我最终还是选择了 javascript 原生函数。

      function intervalFunc() {
        //inside this function you can request to get the date and time then decide what to do and how to do it
        autogens.serverAutoGenerate();//my function to autogenerate bills
      }
      
      setInterval(intervalFunc, 1000);//repeat task after one seconds
      

      在你的node js应用的索引文件或者入口文件中添加代码会使得函数重复执行。您可以根据需要选择更改频率。如果您想每天运行 3 次 cronjob,请获取 24 小时内的秒数,然后除以 3。如果您想在特定时间运行该作业,请使用 new Date(),您可以检查以确定是否现在是执行您的活动的正确时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-26
        • 2012-08-31
        • 1970-01-01
        • 1970-01-01
        • 2023-01-27
        • 1970-01-01
        相关资源
        最近更新 更多