Meteor的服务器端setInterval / clearInterval

我正在创build一个Meteor应用程序,其中包含一些简单的计时器。 按一个定时器上的开始或停止button,每个调用方法来设置或清除间隔定时器等等。 当我setInterval ,我将结果对象存储在当前的计时器文档中,以便稍后当我想要清除间隔计时器时很容易find。 这是我遇到的问题。

当运行Meteor.setInterval()服务器端时,它返回一个对象。 根据node.js文档,这是正常的。 如果我在创build之后logging结果对象,则返回:

 { _idleTimeout: 5000, _idlePrev: { _idleNext: [Circular], _idlePrev: { _idleTimeout: 5000, _idlePrev: [Object], _idleNext: [Circular], _idleStart: 1393271941639, _onTimeout: [Function], _repeat: false }, msecs: 5000, ontimeout: [Function: listOnTimeout] }, _idleNext: { _idleTimeout: 5000, _idlePrev: [Circular], _idleNext: { _idleTimeout: 5000, _idlePrev: [Circular], _idleNext: [Object], _idleStart: 1393271941639, _onTimeout: [Function], _repeat: false }, _idleStart: 1393271941639, _onTimeout: [Function], _repeat: false }, _idleStart: 1393271943127, _onTimeout: [Function: wrapper], _repeat: true } 

如果我从我的文档中检索对象后logging对象,我得到这个:

 { _idleTimeout: 5000, _idlePrev: null, _idleNext: null, _idleStart: 1393271968144, _repeat: true } 

所以,使用clearInterval与此不起作用。 这是我的服务器端代码:

 Meteor.methods({ play: function(entry){ //entry is the document var currentPlayTimer = entry; //Global variable for the interval timer Entries.update({_id: currentPlayTimer._id},{$set:{playing:true}}); //This is mostly to set the status of the play button for the client var IntervalId = Meteor.setInterval(function(){Entries.update({_id: currentPlayTimer._id},{$inc:{time:1},$set:{intervalId: IntervalId}});},5000); //Increment by 1 every 5 seconds, put the object from the interval timer into the current document console.log(IntervalId); }, stop: function(entry){ //entry is the document var currentPlayTimer = entry; IntervalId = currentPlayTimer.intervalId; console.log(IntervalId); Meteor.clearInterval(IntervalId); Entries.update({_id: currentPlayTimer._id},{$set:{playing:false, intervalId: null}}); } }); 

另外,你会注意到在play方法中,我在setInterval函数中设置了intervalId 。 我绝望地尝试了这个,并且工作。 出于某种原因,如果我尝试使用Entries.update({_id: currentPlayTimer._id},{$set:{intervalId: IntervalId}})创build间隔计时器后立即更新文档,则失败。

所有这一切都很好的客户端代码,但我需要做这个服务器端。 我希望定时器能够保持正确的速度,无论您的网页是在5台设备上打开还是不打开。

谢谢你的帮助! 这个项目是我第一次使用meteor或节点上的任何东西,我真的很喜欢它。

这基本上可以归结为两个问题:首先,客户端(至less在Chrome中)和Node中的setIntervalclearInterval的实现是不同的,其次, 您不能在BSON中串行化函数 ,这意味着所有的方法以及包含方法的属性在您尝试将其作为文档插入到服务器上时将从对象中删除。 这就是为什么你随后检索的对象更简单/更小,以及为什么你不能将它传递给clearInterval ,因为它缺less大部分所需的信息。

如果你在客户端logging了setInterval的返回值,你会注意到它只是一个整数,当然这个整数可以被序列化,所以你可以像MongoDB一样从MongoDB中获得完全相同的结果,并且clearInterval工作正常。 在客户端实现set...clearInterval ,我并不是专家,但坦率地说,一个四位数的整数对于这个目的来说似乎并不是特别有效,尽pipe它确实有一些优点。

总之,我不认为你将能够以你在服务器上尝试的方式来处理事情,除非别人能想到一个聪明的方式来连续化interval对象的部分清除它并重build一个适当的对象,一旦它被检索到,但这需要比我拥有更多的Node知识。 否则,我认为你有两个select:

  • 只需将您的间隔存储在某种香草JavaScript对象的内存中。
  • 使用替代对象进行计时,这将允许您存储可序列化的标识符。 过去我已经使用过meteor-cron包,尽pipe简单一些,可能值得一看,看看是否有可能使用这个包或其衍生物。