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

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

The interval's not stopping (not being cleared), if what I've coded above is fine then it'll help me look elsewhere for what's causing the problem. Thanks.

EDIT: Let's assume it completes a few intervals before clearInterval is called which removes the need for setTimeout.

  • no you cann't if these functions are created in the different scope. And as @xtofl wrote it had be better use recursive calls of `setTimeout` function – Sergii Stotskyi Aug 23 '12 at 13:18
  • Why would recursive calls of setTimeout be more appropriate? Thanks for your reply. –  Aug 23 '12 at 13:22
  • `setInterval` has few problems, just read this article - http://javascript.info/tutorial/settimeout-setinterval – Sergii Stotskyi Aug 23 '12 at 13:29
  • 1
    Possible duplicate of [Javascript setInterval clearing itself?](http://stackoverflow.com/questions/9747139/javascript-setinterval-clearing-itself) – Cees Timmerman Feb 23 '16 at 16:20
  • **Use [setTimeout](https://stackoverflow.com/a/24478037/9157799). [Recursive setTimeout isn't actually recursive](https://stackoverflow.com/a/63503930/9157799)** and won't create nested call stack. Watch [this video](https://youtu.be/8aGhZQkoFbQ) if you haven't heard of JS event loop. – M Imam Pratama Mar 02 '23 at 17:02

5 Answers5

156

As long as you have scope to the saved interval variable, you can cancel it from anywhere.

In an "child" scope:

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

In a "sibling" scope:

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

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

You could even pass the interval if it would go out of scope:

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

var foo = function (myInterval) {
    clearInterval(myInterval);
};
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • 2
    How can `myInterval` be passed to `foo` when the `setInterval` hasn't been evaluated yet? – Melab Apr 30 '19 at 02:22
  • 1
    @Melab which of the three code block examples are you referring to? – jbabey May 01 '19 at 13:15
  • Just to note, testing this using `let` instead of `var` doesn't seem to work in a react app – elfico Feb 13 '20 at 10:37
  • @Melab the function inside `setInterval` is not executing on creation but called by `setInterval`, meaning that `myInterval` would already be evaluated – Anime no Sekai Aug 23 '22 at 15:31
11
clearInterval(myInterval);

will do the trick to cancel the Interval whenever you need it. If you want to immediately cancel after the first call, you should take setTimeout instead. And sure you can call it in the Interval function itself.

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

see an EXAMPLE here.

Christoph
  • 50,121
  • 21
  • 99
  • 128
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);

Or

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);
Danil Speransky
  • 29,891
  • 5
  • 68
  • 79
  • 1
    I'm getting a few different answers here, and yours seems to be the ideal one as I'm needing to cancel it 'within' the interval itself. Going by the first part of your answer what I've done in the OP is ok, so I'm going to assume there's no problem there. –  Aug 23 '12 at 13:21
3

From your code what seems you want to do is to run a function and run it again and again until some job is done...

That is actually a task for the setTimeout(), the approach is similar:

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

Simple as that :)

Of course if you REALLY want to use setInterval for some reason, @jbabey's answer seems to be the best one :)

jave.web
  • 13,880
  • 12
  • 91
  • 125
  • If you down vote, please comment on what was wrong/badly done, thank you :) – jave.web Mar 30 '15 at 09:29
  • I know SO is known for "How to do A?" "You don't do A, you do B" but seriously, this is actually [the preferred way](https://stackoverflow.com/q/12092439/9157799#comment133408747_12092439). – M Imam Pratama Mar 02 '23 at 17:10
  • @MImamPratama Although I agree with that for most cases, I wouldn't force that, sometimes you don't care about sequence, but just a regular trigger - in that time setInterval could (still doesn't have to) be a better option – jave.web Mar 03 '23 at 13:48
2

You can do it by using a trick with window.setTimeout

var Interval = function () {
    if (condition) {
        //do Stuff
    }
    else {
        window.setTimeout(Interval, 20);
    };
};
window.setTimeout(Interval, 20);
maniac
  • 1,112
  • 1
  • 13
  • 19