将来几天或几个月进行操作

时间:2012-12-14 17:04:05

标签: javascript email meteor futuretask

我正在试图找出执行任务的最佳方式,例如将来会向用户发送电子邮件。

我的想法是在需要发送电子邮件时存储(在数据库中连同用户数据),并且每天检查用户需要发送电子邮件的内容,并使用Meteor的计时器功能。

// 7 hours in millisec.
Meteor.setTimeout( function() {
    Meteor.call( "sendReminderEmail", ... );
}, 2.52e+7 );

我看到的问题是设置了太多计时器,并阻碍了性能。什么是好的解决方案?

编辑:我的用例基本上包括创建活动的用户,他们将其设置为长期活动或短期活动(基于天,周或月),并且他们会收到关注该事件取决于持续时间。

我想我可以每小时检查一下,但这似乎是一个成本相等的问题。有没有Meteor特定的方法来做到这一点?或者只是一个更好的概念?

编辑2:好的,我已经意识到对我的问题来说并不重要,所以我想在每个时区设置一个计时器,这会发送批量电子邮件。如果用户有一个长期事件并且他们的提醒是本周,那么现在就发送它。基本上它取决于用户的事件持续时间和时区。

所以我的最新问题是,我如何在每天运行某些内容,并考虑到我的问题?

1 个答案:

答案 0 :(得分:2)

假设您想在今天上午9点执行代码,现在是早上8点,您可以创建超时以匹配目标时间内的分钟,然后创建1小时的间隔,并在每次执行时检查时间是否为上午9点如果是的话,执行。

在这个小规模示例中,当时钟显示9秒时,我正在执行executeMe()

实时测试:http://jsbin.com/ikulok/4/edit

<body>
Last run: <span id="time"></span><br>
Next execution: <span id="target"></span>
<script type="text/javascript">
    function executeMe(){
      alert("9 seconds!");
    }
    var timeout = null;
    var interval = null;
    function timer(){
      var now = new Date();
      document.getElementById('time').innerHTML = now;
      document.getElementById('target').innerHTML = new Date(now.getTime()+ 1000);
      //console.log("timer()", now);

      if(now.getSeconds() == 9)
        setTimeout("executeMe();",1); // async

      if(interval == null)
        interval = setInterval("timer()",1000);
    }

    var now = new Date();
    var target = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),now.getSeconds()+1,0);
    //console.log("now", now);
    //console.log("target", target);
    //console.log("diff", target.getTime() - now.getTime());
    document.getElementById('target').innerHTML = target;
    timeout = setTimeout("timer()", target.getTime() - now.getTime() );
  </script>


如果您想每小时而不是每秒运行timer(),只需调整targetsetInterval(),当然还有您的条件

实时测试:http://jsbin.com/ikulok/3/edit

<body>
  Last run: <span id="time"></span><br>
  Next execution: <span id="target"></span>
<script type="text/javascript">
    function executeMe(){
      alert("1:20am!");
    }
    var timeout = null;
    var interval = null;
    function timer(){
      var now = new Date();
      document.getElementById('time').innerHTML = now;
      document.getElementById('target').innerHTML = new Date(now.getTime()+ 1*60*60*1000);
      //console.log("timer()", now);

      if(now.getHour() == 1)
        setTimeout("executeMe();", 20*60*1000); // !!!! this will execute at 1:20am

      if(interval == null)
        interval = setInterval("timer()",1*60*60*1000); // !!!! repeat every hour
    }

    var now = new Date();

    // !!!! targeting next exact hour
    var target = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes()+1,0,0);
    //console.log("now", now);
    //console.log("target", target);
    //console.log("diff", target.getTime() - now.getTime());
    document.getElementById('target').innerHTML = target;
    timeout = setTimeout("timer()", target.getTime() - now.getTime() );
  </script>
</body>