1

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

我的想法是在需要发送电子邮件时存储(与用户数据一起存储在数据库中),并每天检查用户需要发送哪些电子邮件,并使用 Meteor 的 Timer 功能。

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

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

编辑:基本上我的用例包括用户创建一个事件,他们将其设置为长期事件或短期事件(基于天、周或月),并且他们会根据持续时间收到对该事件的跟进。

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

Edit2:好的,我意识到准确性对我的问题并不重要,所以我正在考虑为每个时区设置一个计时器,它会发送大量电子邮件。如果用户有一个长期事件并且他们的提醒是在本周,那么现在就发送它。基本上它取决于事件的持续时间和用户的时区。

所以我更新的问题是,我如何每天运行一些东西,记住我的问题?

4

1 回答 1

2

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

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

现场测试: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>
于 2012-12-14T17:16:46.217 回答