简体   繁体   English

使用Meteor的服务器端setInterval / clearInterval

[英]Server-side setInterval/clearInterval with Meteor

I'm creating a Meteor app that has some simple timers in it. 我正在创建一个Meteor应用程序,里面有一些简单的计时器。 Pressing the start or stop buttons on a timer each call a method to set or clear an interval timer, among other things. 按下定时器上的开始或停止按钮,每个调用一个方法来设置或清除间隔定时器等。 When I setInterval , I store the resulting object in the current timer document so that it is easy to find later when I want to clear the interval timer. 当我setInterval ,我将结果对象存储在当前的计时器文档中,以便以后当我想清除间隔计时器时很容易找到它。 This is where I'm running into issues. 这是我遇到问题的地方。

When running Meteor.setInterval() server-side, it returns an object. 运行Meteor.setInterval()服务器端时,它返回一个对象。 According to the node.js docs, this is normal. 根据node.js文档,这是正常的。 If I log the resulting object after creation, it returns this: 如果我在创建后记录结果对象,则返回以下内容:

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

If I log the object after retrieving it from my document, I get this: 如果我在从文档中检索对象后记录该对象,我会得到:

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

So, using clearInterval with this does not work. 因此,使用clearInterval不起作用。 Here is my server-side code: 这是我的服务器端代码:

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}});

    }
});

Also, you will notice that in the play method, I set intervalId inside of the setInterval function. 另外,您会注意到在play方法中,我在setInterval函数中设置了intervalId I tried this in desperation, and it worked. 我绝望地尝试了这个,它起作用了。 For some reason, if I try to update the document right after creating the interval timer with Entries.update({_id: currentPlayTimer._id},{$set:{intervalId: IntervalId}}) , it fails. 出于某种原因,如果我在使用Entries.update({_id: currentPlayTimer._id},{$set:{intervalId: IntervalId}})创建间隔计时器后立即尝试更新文档,则会失败。

All of this worked great as client-side code, but I need this to be done server side. 所有这些都很适合作为客户端代码,但我需要在服务器端完成。 I want the timer to keep going at the correct pace whether you have the page open on 5 devices or none. 我希望计时器能够以正确的速度继续运行,无论您是在5台设备上打开页面还是没有打开页面。

Thanks for your help! 谢谢你的帮助! This project is my first using Meteor or anything on Node, and I am really enjoying it so far. 这个项目是我第一次使用Meteor或Node上的任何东西,到目前为止我真的非常喜欢它。

This is essentially down to two issues: firstly, that the implementations of setInterval and clearInterval are different on the client (at least in Chrome) and in Node, and secondly that you can't serialise functions in BSON , which means that all your methods, and properties containing methods, are being dropped from the object when you try to insert it as a document on the server. 这主要归结为两个问题:第一, setIntervalclearInterval的实现在客户端(至少在Chrome中)和Node中是不同的,其次, 你不能在BSON中序列化函数 ,这意味着你的所有方法当您尝试将其作为文档插入服务器时,将从对象中删除包含方法的属性。 That's why the object you subsequently retrieve is so much simpler/smaller, and why you can't pass it to clearInterval , as it's missing most of the required information. 这就是为什么你随后检索的对象更简单/更小,以及为什么你不能将它传递给clearInterval ,因为它缺少大部分所需的信息。

If you log the return value of setInterval in the client, you'll notice that it's just an integer, which can of course be serialised, and so you get exactly the same thing out of the MongoDB as you put in, and clearInterval works fine. 如果你在客户端中记录setInterval的返回值,你会发现它只是一个整数,当然可以被序列化,所以你得到的东西与MongoDB完全相同,并且clearInterval工作正常。 I am no expert at all on the client implementation of set... and clearInterval , but frankly a four-digit integer doesn't seem particularly robust for this purpose, although it does have some advantages that you've identified. 我对set...clearInterval的客户端实现完全不是专家,但坦率地说,四位数整数对于此目的似乎并不特别强大,尽管它确实具有您已经确定的一些优点。

In summary, I don't think you're going to be able to go about things the way in which you're attempting on the server, unless somebody else can think of a smart way of serialising the part of the interval object which is required for clearing it and rebuilding an appropriate object once it's been retrieved, but this requires more knowledge of Node than I possess. 总而言之,我不认为你能够按照你在服务器上尝试的方式进行操作,除非其他人能够想到一种智能的方法来序列化interval对象的一部分,这是一旦检索到它就需要清除它并重建一个适当的对象,但是这需要比我拥有的Node更多的知识。 Otherwise, I think you have two options: 否则,我认为你有两个选择:

  • Simply store your intervals in memory in some kind of vanilla javascript object. 只需将您的间隔存储在某种类型的vanilla javascript对象的内存中。
  • Use an alternative object for timing which would allow you to store a serialisable identifier. 使用备用对象进行计时,以便存储可序列化的标识符。 I have used the meteor-cron package in the past, albeit briefly, and it may be worth a look to see if this is possible using that package or some derivative thereof. 我过去曾使用过meteor-cron软件包,虽然很简单,但值得一看,看看是否可以使用该软件包或其衍生产品。

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

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