繁体   English   中英

使用Meteor的服务器端setInterval / clearInterval

[英]Server-side setInterval/clearInterval with Meteor

我正在创建一个Meteor应用程序,里面有一些简单的计时器。 按下定时器上的开始或停止按钮,每个调用一个方法来设置或清除间隔定时器等。 当我setInterval ,我将结果对象存储在当前的计时器文档中,以便以后当我想清除间隔计时器时很容易找到它。 这是我遇到问题的地方。

运行Meteor.setInterval()服务器端时,它返回一个对象。 根据node.js文档,这是正常的。 如果我在创建后记录结果对象,则返回以下内容:

{ _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 }

如果我在从文档中检索对象后记录该对象,我会得到:

{ _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}})创建间隔计时器后立即尝试更新文档,则会失败。

所有这些都很适合作为客户端代码,但我需要在服务器端完成。 我希望计时器能够以正确的速度继续运行,无论您是在5台设备上打开页面还是没有打开页面。

谢谢你的帮助! 这个项目是我第一次使用Meteor或Node上的任何东西,到目前为止我真的非常喜欢它。

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

如果你在客户端中记录setInterval的返回值,你会发现它只是一个整数,当然可以被序列化,所以你得到的东西与MongoDB完全相同,并且clearInterval工作正常。 我对set...clearInterval的客户端实现完全不是专家,但坦率地说,四位数整数对于此目的似乎并不特别强大,尽管它确实具有您已经确定的一些优点。

总而言之,我不认为你能够按照你在服务器上尝试的方式进行操作,除非其他人能够想到一种智能的方法来序列化interval对象的一部分,这是一旦检索到它就需要清除它并重建一个适当的对象,但是这需要比我拥有的Node更多的知识。 否则,我认为你有两个选择:

  • 只需将您的间隔存储在某种类型的vanilla javascript对象的内存中。
  • 使用备用对象进行计时,以便存储可序列化的标识符。 我过去曾使用过meteor-cron软件包,虽然很简单,但值得一看,看看是否可以使用该软件包或其衍生产品。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM