关于javascript:ClearInterval不清除SetInterval

ClearInterval not clearing SetInterval

当我们使用setInterval返回的值调用clearInterval时,它将使该值成为null或未定义。

我正在调用clearInterval来清除setInterval,但显然setInterval的值保持不变,即使调用clearInterval之后也不会改变。 t是否应该为null或undefined? 这是我的代码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var setIntervalId; // declared in global scope
//lined of code

function autorefresh() {
  if (statesCount > 0) {
    setIntervalId = setInterval(function() {
        //lines of code
        // calling some handler
    }, 30000);
  }

  if (statesCount === 0) {
    clearInterval(setIntervalId);
  }
}

如您所见,我每隔30秒调用一次setInterval函数,第一次调用时会为setIntervalId分配一些值,但是即使在调用clearInterval之后,该值仍然存在。 调用clearInterval后应该为null还是未定义?如果应该为null或未定义,我应该在这里做什么我已经在全局范围内定义了setIntervalId。


Should it become null or undefined after calling clearInterval?

没有。

它只是个数字。清除间隔后,该数字只是历史上的好奇心。

如果愿意,可以将undefined显式分配给它,然后再将其用于clearInterval。除非您使用它来跟踪当前是否正在定期运行函数,否则无需执行此操作。


函数clearInterval不会清除传递给它的值。如果要清除它,必须自己做

1
2
clearInterval(setIntervalId);
setIntervalId = undefined;

请注意,它似乎没有像您正确地保护对setInterval的初始调用。这可能导致多次拨打电话,因此您需要设置多个间隔。我认为您应该将初始if块扩展为以下内容

1
2
3
if (statesCount > 0 && typeof(setIntervalId) === 'undefined') {
  ...
}


好的,我经历了同样的问题太多次了,通常我会顺其自然,
但是大多数时候,我意识到清除间隔后间隔会继续运行,这可能会影响设备的性能(就像有一个无限循环)。

所以我做了一些研究,发现了问题所在,然后编写了一个简单的代码来解决它。

现在,在大多数情况下,当您启动一个间隔(很可能是由事件触发)时,便会声明该间隔的多个实例(无论出于何种原因)...

因此,当您稍后清除间隔时,您只清除* top-level间隔,然后设置下一个级别间隔。
(顶层可能不是正确的词)

因此,为了真正清除间隔,我使用了以下方法:

设置间隔:

1
2
if(!timer)  
    timer =setInterval(myFunction, 1000);

清除间隔:

1
2
3
4
5
clearInterval(timer);
timer=null;
while (timer!== null){
    timer=null;
}

您可能决定清除while循环内的时间间隔,但是我发现这对我有用,并且比之有效。

Make sure you check the scope of the interval variable (i.e timer in the case above)


如果您一次只允许一个时间间隔,则此方法应该可以正常工作。

如果允许多个间隔,则需要保持对每个实例的访问权限以停止它们。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var setIntervalId; // declared in global scope
var statesCount = 1; // simulate active state
//lined of code


function autorefresh() {
  if (statesCount > 0) {
    console.log('started');
    setIntervalId = setInterval(function() {
      // just to see whats happening in console
      console.log(statesCount);

      // performe interval checks inside the interval loop not outside if you want to stop it automaticaly
      if (statesCount === 0) {
        clearInterval(setIntervalId);
      }
      // lines of code
      // calling some handler
    }, 1000); // repeat every 1s
  };
}

// run interval
autorefresh();

// stimulate change of stateCount after 5s
// setTimeout(function(){
//   statesCount = 1;
// },5000);

// clear interval after 10s
setTimeout(function(){
  clearInterval(setIntervalId);
  console.log('stoped');
},10000);

  • CODEPEN示例