繁体   English   中英

setInterval仅触发一次

[英]setInterval fires only once

我正在尝试创建一个自包含计时器,其中所有变量都在一个对象内。

在大多数情况下,它都能正常工作,但我可以将其触发一次。 我想念什么?

    function Countdown()
    {
        this.appId = null;
        this.timerId = null;
        this.seconds = null;

        this.decrementCounter = function (instant)
        {
            if (instant == null)
                return;

            instant.tick();
            if (instant.seconds === 0)
            {
                instant.tickEnd();
                instant.stop();
            }
            instant.seconds--;
        };
        this.tick = function ()
        {
            var xx = this.appId
        };
        this.tickEnd = function ()
        {
            var xx = this.appId
        };
        this.start = function ()
        {
            clearInterval(this.timerId);
            this.timerId = setInterval(this.decrementCounter(this), 1000);
        };
        this.stop = function ()
        {
            clearInterval(this.timerId);
        };
    }

我对代码进行了一些修改,并将包含setInterval的行更改为:

this.timerId = setInterval((function(scope) {return function() {scope.decrementCounter(scope);};})(this), 1000);

这些函数在setInterval内部运行,并在window范围内运行。 它仅运行一次,因为您不会仅仅传递函数本身的结果。 您需要返回实际函数或传递调用它的匿名函数。

jsfiddle演示: http : //jsfiddle.net/2gLdL/1/

您正在调用函数,而不是分配引用

this.timerId = setInterval(this.decrementCounter(this), 1000); 

您似乎以“ this”作为参数传递很奇怪。

使用bind()

this.timerId = setInterval(this.decrementCounter.bind(this, this), 1000); 

或关闭

var that = this;
this.timerId = setInterval(function(){that.decrementCounter(that); }, 1000); 

在下面的代码中:

this.timerId = setInterval(this.decrementCounter(this), 1000);

您正在立即执行此操作:

this.decrementCounter(this)

因此,返回值就是setInterval每秒调用的值。 通常,您希望传递一个函数闭包,如下所示:

var _this = this; //make sure your variable is available in the scope that follows
this.timerId = setInterval(function() { this.decrementCounter(_this); }, 1000);

然后,当您的计时器执行时,将调用该函数,然后该函数执行您想要的操作。 另一个选择是将第一个参数作为字符串传递,例如“ callAFunction('blah')”,该字符串将每秒进行评估并执行,但我相信上面就是您想要的。

尝试这个:

setInterval(function(){Countdown()},500);

为另一个创建简单秒表的问题提供了答案

您可以稍微修改代码以递减计数而不是递增计数。

这是一个jsbin演示


原始片段

var Stopwatch = function(elem, options) {

  var timer       = createTimer(),
      startButton = createButton("start", start),
      stopButton  = createButton("stop", stop),
      resetButton = createButton("reset", reset),
      offset,
      clock,
      interval;

  // default options
  options = options || {};
  options.delay = options.delay || 1;

  // append elements     
  elem.appendChild(timer);
  elem.appendChild(startButton);
  elem.appendChild(stopButton);
  elem.appendChild(resetButton);

  // initialize
  reset();

  // private functions
  function createTimer() {
    return document.createElement("span");
  }

  function createButton(action, handler) {
    var a = document.createElement("a");
    a.href = "#" + action;
    a.innerHTML = action;
    a.addEventListener("click", function(event) {
      handler();
      event.preventDefault();
    });
    return a;
  }

  function start() {
    if (!interval) {
      offset   = Date.now();
      interval = setInterval(update, options.delay);
    }
  }

  function stop() {
    if (interval) {
      clearInterval(interval);
      interval = null;
    }
  }

  function reset() {
    clock = 0;
    render();
  }

  function update() {
    clock += delta();
    render();
  }

  function render() {
    timer.innerHTML = clock/1000; 
  }

  function delta() {
    var now = Date.now(),
        d   = now - offset;

    offset = now;
    return d;
  }

  // public API
  this.start  = start;
  this.stop   = stop;
  this.reset  = reset;
};

暂无
暂无

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

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