Meteor 当我浏览到应用程序的其他页面时,如何创建一个持续的倒计时计时器?

Meteor 当我浏览到应用程序的其他页面时,如何创建一个持续的倒计时计时器?,meteor,Meteor,我正在制作一个简单的应用程序,启动一个倒计时计时器,当计时器过期时,它会显示一个模板。在该模板上,我回答一系列问题,然后将答案提交到数据库 目前,我的倒计时计时器是用JavaScript编写的,如下所示: Template.start.events({ 'click .startTimer': function() { $("#timer").text(); (function() { var wait = 2;

我正在制作一个简单的应用程序,启动一个倒计时计时器,当计时器过期时,它会显示一个模板。在该模板上,我回答一系列问题,然后将答案提交到数据库

目前,我的倒计时计时器是用JavaScript编写的,如下所示:

    Template.start.events({
    'click .startTimer': function() {

        $("#timer").text();

        (function() {
            var wait = 2;
            var countSpan = $('#timer span');

            function countdown() {

                wait -= 1;

                if (wait > 0) {
                    countSpan.text(wait);
                    setTimeout(countdown, 1000);
                    $('.startTimer').prop("disabled", true);
                    Session.set('done', false);

                } else {
                    Session.set('done', true);
                    $('.startTimer').prop("disabled", false);
                    countSpan.text("Complete checkup then keep working!");

                }
            }
            setTimeout(countdown, 1000);

        }());
    }
});
问题是,当我离开打印倒计时的页面时,倒计时不会持续。


如何在我的应用程序中创建一个倒计时计时器,当我导航到应用程序中的其他页面时,它将继续运行?

这个伪想法怎么样:

  • 一旦你离开了页面(标签模糊),保存 会话中具有当前时间戳的变量
    Session.set(“leavingAt”,new Date())

  • 返回页面(等效选项卡焦点)后,使用当前时间戳保存新变量
    Session.set(“returningAt”,new Date())

  • 添加/减去两者之间的差异(取决于您的实现方式),并更新倒计时计时器

  • 您可以使用Meteor方法启动服务器上的计时器

    // call method from template
    Meteor.call('startTimer', function() {
      // handle timer finished logic
    });
    
    //server
    Meteor.methods({
      startTimer: function() {
        Meteor.setTimeout(function() {
          //do something
          return;
        }, ms)
      }
    });
    

    我认为即使您使用的是不同的模板,您的回调仍然会被触发,但我不能100%确定。

    我最终使用meteorhacks:async来完成这一点。代码如下:

        function delayedMessge(callback) {
            Meteor.setTimeout(function() {
                callback(null, true)
            }, 1000)
        }
    
        var wrappedDelayedMessage = Async.wrap(delayedMessge);
    
        Meteor.methods({
            'abc': function() {
                var response = wrappedDelayedMessage();
                return response;
            }
        });
    
        Template.start.events({
    
        'click .start': function() {
    
            Meteor.call('abc', function(error, response){
                var timeup = response
                //I'm setting this session to true, then in a helper
                //that isn't shown here, I'm getting the Session and
                //which displays the template
                Session.set('done', timeup)
            });
          }
        })
    

    阿齐姆的回答把我引向了正确的方向,但并不完全正确。我确实在一个方法中运行了setTimeout,但出现了一个问题。与Meteor.call关联的回调会立即执行,但mehod中的setTimeout尚未完成。使用meteorhacks:async包,Meteor.call回调函数将等待setTimeout触发

    你的回答把我引向了正确的方向。在服务器上执行setTimeout是最好的方法。但是,对于Meteor.call,回调函数在setTimeout完成之前执行。