Javascript setInterval不及时返回ID

时间:2016-04-07 19:29:02

标签: javascript setinterval clearinterval

我正在使用Javascript(没有JQuery)并且遇到了我正在尝试调试的情况。

我正在使用setInterval,间隔为1秒,以监控被指示移动的物理硬件。一旦硬件移动到正确的位置,我就会使用setInterval调用返回的ID调用clearInterval。

一切都按预期工作 - 除非......硬件无法正常工作。

当硬件无法正常工作时,我第一次尝试移动硬件会返回错误(这应该是它的工作方式)。

当我收到错误时,我想通过调用clearInterval来停止Interval。

然而,我所看到的是......

我调用setInterval - 它会立即触发我第一次移动硬件的请求(在这种情况下)会很快返回错误(无法移动硬件)。

似乎更快地返回错误,setInterval将Interval ID存储到结果变量中。因此,我对clearInterval的调用失败,因为ID为零,而不是正确的ID。

我已经验证了这一点......事实上,当setInterval调用返回ID时,会有很大的延迟。所以这样的事情正在发生:

  • 我调用setInterval并期待ID返回
  • setInterval调用我的函数,它试图移动硬件
  • 硬件移动失败,我的函数尝试调用clearInterval,但原始的setInterval尚未返回正确的ID
  • clearInterval失败,因为ID为零,而不是正确的
  • 我的功能继续被称为

我试过clearInterval 0到100之间的所有值(如其他帖子所示) - 但这似乎并没有停止计时器(我回来的ID几乎总是2,所以我是不清楚为什么不清楚它。)

确保我及时收回身份证的建议方法是什么?

注意...不使用(并且不能因为要求)JQuery。只是纯粹的javascript。

非常感谢!

编辑:添加代码......

全球声明:

var drawIntervalID = 0;

以下是设置Interval的代码:

drawIntervalID = setInterval(masks_animate,1000);

masks_animate函数是一个简单的直接函数,只需做出一些决定并调用其他函数。具体来说,它调用moveCarousel来实际移动硬件。如果出现问题,moveCarousel也是试图清除间隔的函数:

// This function will move the carousel
function moveCarousel(mask) {
   var res,i,ss;
   setLO("","#000000");
   if (training_mode) {
      alert("Attempt to move Carousel in Training Mode ignored");
   } else {
      res = sendRequest("MOVE:"+mask);
      i   = res.indexOf('OK:');
      if (i >= 0) {
          ss  = res.slice(i);
          res = ss.split(":");
          if (res.length == 2) {
              res[1]  = res[1].replace(/(\r\n|\n|\r)/gm,"");
              setLO(res[1],"#00ff00");
          } else {
              alert("Carousel MOVE request returned bad data ("+ss+")");
              clearTimer();
              masksDisplay();
          }
      } else {
          i = res.indexOf('ERR:');
          if (i >= 0) {
              ss  = res.slice(i);
              res = ss.split(":");
              if (res.length == 2) {
                  res[1]  = res[1].replace(/(\r\n|\n|\r)/gm,"");
                  setLO(res[1],"#ff0000");
              } else alert("Carousel MOVE request returned bad data ("+ss+")");
           } else alert("Carousel MOVE request returned bad data ("+res+")");
           clearTimer();
           masks_moving = 0;
           masksDisplay();
       }
   }
   return false;
}

要看的是小写,我正在寻找“ERR:”(这是硬件的错误条件。在这种情况下,我调用clearTimer(),如下所示:

// This function will clear the timer
function clearTimer() {
    if (drawIntervalID != 0) {
        clearInterval(drawIntervalID);
        drawIntervalID = 0;
    } else {
        for (var i=0; i<100; i++) clearInterval(i);
        drawIntervalID = 0;
    }
}

就像我说的那样 - 除了硬件立即返回错误的情况外,它完全有效,在这种情况下我的drawIntervalID尚未设置。

编辑:我修改了代码,将初始drawIntervalID设置为NULL(非零)并检查NULL。没有差别。

1 个答案:

答案 0 :(得分:0)

您似乎过度管理并错误地初始化代码中的计时器ID。而且,由于您遇到计时器问题,这将是一个合乎逻辑的起点。

只需将您的计时器变量初始化为null(不是0或任何其他整数),并在需要时直接调用clearInterval()(而不是将控制传递给clearTimer函数) 。您无法使用clearTimer()功能,因为它不提供对您实际有用的任何功能 - 它只是使代码复杂化的更多代码。

在使用代码之前,您可能会成为优化代码的受害者。