我正在试图找出执行任务的最佳方式,例如将来会向用户发送电子邮件。
我的想法是在需要发送电子邮件时存储(在数据库中连同用户数据),并且每天检查用户需要发送电子邮件的内容,并使用Meteor的计时器功能。
// 7 hours in millisec.
Meteor.setTimeout( function() {
Meteor.call( "sendReminderEmail", ... );
}, 2.52e+7 );
我看到的问题是设置了太多计时器,并阻碍了性能。什么是好的解决方案?
编辑:我的用例基本上包括创建活动的用户,他们将其设置为长期活动或短期活动(基于天,周或月),并且他们会收到关注该事件取决于持续时间。
我想我可以每小时检查一下,但这似乎是一个成本相等的问题。有没有Meteor特定的方法来做到这一点?或者只是一个更好的概念?
编辑2:好的,我已经意识到对我的问题来说并不重要,所以我想在每个时区设置一个计时器,这会发送批量电子邮件。如果用户有一个长期事件并且他们的提醒是本周,那么现在就发送它。基本上它取决于用户的事件持续时间和时区。
所以我的最新问题是,我如何在每天运行某些内容,并考虑到我的问题?
答案 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()
,只需调整target
和setInterval()
,当然还有您的条件
实时测试: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>