Javascript setInterval函数如何清除自身?

91
myInterval = setInterval(function(){
     MyFunction();
},50);

function MyFunction()
{
    //Can I call clearInterval(myInterval); in here?
}

如果我所编写的代码没问题,那么间隔是不会停止(不会被清除),这将帮助我在其他地方寻找问题的原因。谢谢。

编辑:假设在调用clearInterval之前完成了几个间隔,这就不需要setTimeout了。


不行,如果这些函数在不同的作用域中创建,就不能这样做。正如@xtofl所写的那样,最好使用setTimeout函数的递归调用。 - Sergii Stotskyi
为什么递归调用setTimeout更合适?感谢您的回复。 - user1017882
setInterval存在一些问题,只需阅读此文章 - http://javascript.info/tutorial/settimeout-setinterval - Sergii Stotskyi
1
可能是Javascript setInterval清除自身?的重复问题。 - Cees Timmerman
使用 setTimeout递归 setTimeout 实际上并不是递归,也不会创建嵌套的调用堆栈。如果您还没有听说过 JS 事件循环,请观看 这个视频 - M Imam Pratama
5个回答

158
只要您在保存的interval变量的作用域内,就可以从任何位置取消它。
在一个“子”作用域中:
var myInterval = setInterval(function(){
     clearInterval(myInterval);
},50);

在「同级」作用域中:

var myInterval = setInterval(function(){
     foo();
},50);

var foo = function () {
    clearInterval(myInterval);
};

如果需要,你甚至可以传递该时间间隔,即使它超出了作用域:

var someScope = function () {
    var myInterval = setInterval(function(){
        foo(myInterval);
    },50);
};

var foo = function (myInterval) {
    clearInterval(myInterval);
};

2
setInterval还没有被评估时,如何将myInterval传递给foo函数? - Melab
1
@Melab你指的是三个代码块中的哪一个例子? - jbabey
只是注意,使用 let 而不是 var 在 React 应用程序中似乎无法正常工作。 - elfico
@Melab setInterval 内部的函数不是在创建时执行,而是由 setInterval 调用,这意味着 myInterval 已经被评估。 - Anime no Sekai

11
clearInterval(myInterval);

如果你想随时取消 Interval,可以使用 clearInterval。如果你想在第一次调用后立即取消,应该使用 setTimeout。当然,你也可以在 Interval 函数本身中调用它。

var myInterval = setInterval(function() {
  if (/* condition here */){
        clearInterval(myInterval);
   } 
}, 50);

你可以在这里查看一个示例。


1
但是这个函数可以在其自身的时间间隔内被调用吗?也就是说,它能够停止自己吗? - user1017882
没问题,我已经删除了我的评论。 - user1017882

3
var interval = setInterval(function() {
  if (condition) clearInterval(interval); // here interval is undefined, but when we call this function it will be defined in this context
}, 50);

或者

var callback = function() { if (condition) clearInterval(interval); }; // here interval is undefined, but when we call this function it will be defined in this context
var interval = setInterval(callback, 50);

1
我在这里得到了几个不同的答案,而你的答案似乎是最理想的,因为我需要在“间隔”内取消它。根据你回答的第一部分,我在 OP 中所做的是可以的,所以我会假设那里没有问题。 - user1017882

3

根据您的代码,似乎您想要运行一个函数并一遍又一遍地运行它,直到某个任务完成...

这实际上是由setTimeout()执行的任务,方法类似:

    var myFunction = function(){
      if( stopCondition ) doSomeStuff(); //(do some stuff and don't run it again)
        else setTimeout( myFunction, 50 );
    }
    myFunction(); //immediate first run 

就是这么简单 :)

当然,如果你真的有某种原因想要使用setInterval,@jbabey的回答似乎是最好的 :)


如果你给我点踩,请评论一下哪里做得不好/有问题,谢谢 :) - jave.web
我知道SO以“如何做A?”“你不做A,你做B”而闻名,但说真的,这实际上是首选方式 - M Imam Pratama
虽然我同意大多数情况下的观点,但我不会强制执行。有时你并不关心顺序,只需要一个常规触发器 - 这种情况下,setInterval可能(但不一定)是更好的选择。 - jave.web

2

你可以通过使用window.setTimeout技巧来实现

var Interval = function () {
    if (condition) {
        //do Stuff
    }
    else {
        window.setTimeout(Interval, 20);
    };
};
window.setTimeout(Interval, 20);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接