简体   繁体   English

setTimeout仅在Meteor中与console.log一起运行

[英]setTimeout only running with a console.log in Meteor

I have the following code on a Meteor app 我在Meteor应用上有以下代码

Template.timer.helpers({    
       currentTime: function(){
            //keep the current time stored in the session
            timeout = Meteor.setTimeout(function () {
              Session.set("now", new Date());
            }, 1000);
            console.log(Session.get('now'));
});
Template.timer.events({
    'click': function(){
        //some code
        Session.set("now", new Date());
        //some more code
    }
});

When there is a click event I get multiple timeouts running simultaneously, even though I'm only updating the Session once. 当发生点击事件时,即使我只更新一次Session,我也会同时运行多个超时。

But, if I remove console.log in timer.helpers, then the setTimeout doesn't update the Session at all (only the Click does). 但是,如果我删除了timer.helpers中的console.log,则setTimeout根本不会更新会话(只有Click会更新)。

What am I missing?? 我想念什么? Is there a better way to keep a current (reactive) client time stored? 有没有更好的方法来保存当前(反应性)客户端时间?

If you want to update a client session with the latest client time every second, you can use Meteor.setInterval instead and set it up after the template has rendered. 如果要每秒更新一次具有最新客户端时间的客户端会话,则可以改用Meteor.setInterval并在渲染模板后进行设置。 For example: 例如:

Template.timer.rendered = function() {
  Meteor.setInterval( function() {
    Session.set("now", new Date());
  }, 1000);
};

Template.timer.helpers({
  currentTime: function() {
    return Session.get("now");
  }
});

This is basically the essence of reactivity. 这基本上是反应性的本质。

When a function which reruns reactively (which includes helper functions and autorun blocks) gets the value of a reactive object anywhere within its code, the function is registered as a dependency for that object. 当以反应方式重新运行的函数(包括帮助函数和自动运行块)在其代码中的任何位置获取反应对象的值时,该功能将注册为该对象的依赖项。 When the value of the object changes, the function's computation will be invalidated by the change of value, and the function will rerun itself. 当对象的值更改时,该函数的计算将因值的更改而无效,并且该函数将自行重新运行。

So what happens here is that the console.log is, most importantly, get ting the value of your session variable, which makes the helper rerun every time it's set . 因此,最重要的是,这里发生的情况是console.log get了会话变量的值,这使得每次set helper都会重新运行。 However, it also sets a timeout callback which itself set s the value of the variable (to a value which is guaranteed to be different as it's the current time), which means the helper function will call itself again as soon as the timeout callback has run. 但是,它还会设置一个超时回调,该回调本身set变量的值set为(确保与当前时间不同的值),这意味着辅助函数将在超时回调具有后立即再次调用自身。跑。

If you remove the console.log , you also remove the Session.get , which will remove the dependency and the helper will no longer rerun when the value of the Session variable is changed, whether by the timeout callback or elsewhere. 如果删除console.log ,那么还将删除Session.get ,它将删除依赖关系,并且在更改Session变量的值时(无论是通过超时回调还是其他方式),帮助程序将不再重新运行。

There are a lot of resources on the web to help understand reactivity, which is probably the most fundamental concept in learning Meteor. 网上有很多资源可以帮助您了解反应性,这可能是学习流星的最基本概念。

https://meteorhacks.com/journey-into-meteors-reactivity.html http://manual.meteor.com/#deps-transparentreactiveprogramming http://richsilv.github.io/meteor/meteor-reactive-data-types/ https://meteorhacks.com/journey-into-meteors-reactivity.html http://manual.meteor.com/#deps-transparentreactiveprogramming http://richsilv.github.io/meteor/meteor-reactive-data-types /

  Tracker.autorun(function(){
            //keep the current time stored in the session
            timeout = Meteor.setInterval(function () {
              var se = Session.get("now");
              if(se === true){
                se = new Date();
                console.log(se);
              }else{
                 console.log("until click i start")
              }
            }, 1000);
            //console.log(Session.get('now'));
  });


Template.timer.events({
    'click': function(){
      console.log("clicked")
        Session.set("now",true);
    }
});

Try this code, this is what i change. 试试这个代码,这就是我的改变。

First, we just set a true/false , session inside the event, just to let know when the user, click the button. 首先,我们只在事件内部设置一个true/false会话,以告知用户何时单击按钮。

and later, we put the the session inside a Tracker.autorun(function(){}) , with auto run we look for any change on the sessions, and remove the timeout for a interval, docs here 稍后,我们将会话放入Tracker.autorun(function(){}) ,使用自动运行,我们会查找会话中的任何更改,并删除一段时间的超时,请点击此处

third, on the timeout variable, we look for variables changes, if "now" === true , we start the timer, if not, we send a friendly console.log . 第三,在超时变量上,我们寻找变量的变化,如果"now" === true ,我们启动计时器,否则,我们发送一个友好的console.log

That works form me. 那对我有用。

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

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