在对象的方法中遇到setInterval问题

时间:2015-02-24 19:29:08

标签: javascript setinterval

我无法弄清楚为什么当我调用对象的reset方法时,计时器仍为null。我的对象的简化版本在下面,然后是构造新对象并运行代码的jQuery。有关我的具体问题,请参阅大写评论。谢谢!

    var countdownTimer = {
        // Default vars
        milliseconds: 120000,
        interval: 1000, 
        timer: false,

        /* ... stuff ... */
        countdown: function () {
            var root = this;
            var originalTime = root.milliseconds;
            /* ... stuff */
            // IN MY MIND THIS NEXT LINE SETS THE INSTANCE OF THIS OBJECT'S TIMER PROPERTY TO THE setIterval's ID.  BUT DOESN'T SEEM TO BE CORRECT. WHY?
            root.timer = setInterval(function () {
                if (root.milliseconds < 1) {
                    clearInterval(root.timer); // THIS LINE SEEMS TO WORK
                    root.countdownComplete(); // callback function
                    return false;
                }
                root.milliseconds = root.milliseconds - root.interval;

                /* .... stuff ... */
            }, root.interval);
        },
        start: function (ms) {
            if (ms) {
                this.milliseconds = ms;
            }
            if(this.timer) {
                clearInterval(this.timer);  // NOT SURE IF THIS WORKS OR NOT
            }
            this.countdown();
        },
        reset: function (ms) {
            var root = this;
            if(root.timer) {
                clearInterval(root.timer); // THIS DOES NOT WORK
            } else {
                console.log('timer not exist!!!!'); // ALWAYS END UP HERE. WHY?
            }
            /* .... stuff ... */
        },
        countdownComplete: function() {  }

    };

// Setting up click events to create instances of the countdownTimer
$(function () {
    var thisPageCountdown = 4000;

    $('[data-countdown]').on('click', '[data-countdown-start], [data-countdown-reset]', function () {
        var $this = $(this);
        var $wrap = $this.closest('[data-countdown]');
        // create instance of countdownTimer
        var myCountdown = Object.create(countdownTimer);

        if ($this.is('[data-countdown-start]')) {
            $this.hide();
            $('[data-countdown-reset]', $wrap).css('display', 'block');
            myCountdown.$wrap = $wrap;
            myCountdown.start(thisPageCountdown);
            // myCountdown.countdownComplete = function() {
            //  alert("Updated Callback!");
            // };
        } 

        if ($this.is('[data-countdown-reset')) {
            $this.hide();
            $('[data-countdown-start]', $wrap).css('display', 'block');

            // RESET CALLED HERE BUT DOESN'T WORK RIGHT. SAYS myCountdown.timer IS STILL null. WHY?
            myCountdown.reset(thisPageCountdown); 
        }

    });
});

2 个答案:

答案 0 :(得分:1)

当您在单击函数回调中使用var myCountdown = Object.create(countdownTimer);时,您只能对该回调进行限定,一旦回调执行,它就会被垃圾回收。您只需要创建countdownTimer的一个实例,它应该在您的点击事件处理程序之外。

var thisPageCountdown = 4000;
// create instance of countdownTimer
var myCountdown = Object.create(countdownTimer);

$('[data-countdown]').on('click', '[data-countdown-start], [data-countdown-reset]', function () {
    var $this = $(this);
    var $wrap = $this.closest('[data-countdown]');

答案 1 :(得分:0)

TL; DR 您可以避免在静态方法中使用关键字this来解决您的问题。

在静态javascript方法中使用关键字this时,它指的是调用点中最后一个点之前的项目。例如:

foo.bar(); // inside, this will refer to foo
foo.bar.foobar(); //inside, this will refer to foo.bar
var a = foo.bar.foobar();
a(); //this will refer to either null or window - oops

要防止出现这种情况,您应始终在静态方法中使用完全限定名称引用,而不是依赖this关键字。

上面的例子:

reset: function (ms) {
  //var root = this; // don't do this
  if(countdownTimer.timer) {
    clearInterval(countdownTimer.timer); 
  } else {
    console.log('timer not exist!!!!'); 
  }
  /* .... stuff ... */
}