-1

THIS IS NOT A DUPLICATE!

I have a piece of JavaScript with what I call a "nested" setInterval; one setInterval that calls a function with another setInterval.

What i want is when the "outer" setInterval calls the function when the "inner" setInterval is already running, I want the "inner" setInterval to stop it's original interval and start again fresh.

So:

  1. Outer setInterval fires.
  2. Outer setInterval calls function with inner setInterval.
  3. Inner setInterval fires.

... inner runs for a while

  1. Outer setInterval fires ... again.
  2. Outer setInterval calls inner setInterval ... again
  3. Inner setInterval stops it's original run.
  4. Inner setInterval starts a fresh, new run.

See my example below:

    <!DOCTYPE html>
    <html>
        <head>
            <title></title>
            <style type="text/css">
                div {
                    margin: 100px 100px;
                }
            </style>
            <script type="text/javascript">
    
                let alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
    
                function start(){
                    var the_button = document.getElementById('the_button');
                    the_button.addEventListener('click', testFunction);
                }
    
                function testFunction(){
                    console.log("Starting ...");
                    if(myIntervalVal) clearInterval(myIntervalVal);
                    var myIntervalVal = setInterval(printAlphabet, 10000);
                }
    
                function printAlphabet(){
                    var i = 0;
                    console.log(alphabet[i]);
                    if(mySubInterval) clearInterval(mySubInterval);
                    var mySubInterval = setInterval(function(){
                        i++;
                        if(i === alphabet.length) i = 0;
                        console.log(alphabet[i]);
                    }, 1000);
                }
            </script>
        </head>
        <body onload="start();"><div><button type="button" id="the_button">click me</button></div></body>
    </html>

The way I feel this should work is:

outer fires
    inner prints
    A
    B
    C
    D
    E
    F
outer is fired again
    inner stops printing
    inner prints
    A
    B
    C
    D
    E
    F
    ...

Is this not possible?

Brian
  • 1,726
  • 2
  • 24
  • 62
  • `var myIntervalVal` makes it local to that block. The variable does not persist over multiple invocations. Declare it outside the block instead, so that it's persistent and can be cleared. – CertainPerformance Oct 31 '20 at 00:54

2 Answers2

0

It would work, but you need to lift the mySubInterval out of the printAlphabet function.

var mySubInterval;
function printAlphabet(){
  var i = 0;
  console.log(alphabet[i]);
  if(mySubInterval) clearInterval(mySubInterval);
  mySubInterval = setInterval(function(){
    // …

Same rule applies to myInterval and testFunction.

hackape
  • 18,643
  • 2
  • 29
  • 57
0

While the other solution works, You dont' need to do that; you should only need to move if(mySubInterval) clearInterval(mySubInterval); to the bottom of the printAlphabet() function. Before, you were checking if mySubInterval was truthy before it was declared, but now your browser "knows" that it's truthy and will do the clearInterval()

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <style type="text/css">
            .div {
                margin: 100px 100px;
            }
        </style>
        <script type="text/javascript">

            let alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];

            function start(){
                var the_button = document.getElementById('the_button');
                the_button.addEventListener('click', testFunction);
            }

            function testFunction(){
                console.log("Starting ...");
                if(myIntervalVal) clearInterval(myIntervalVal);
                var myIntervalVal = setInterval(printAlphabet, 10000);
            }

            function printAlphabet(){
                var i = 0;
                console.log(alphabet[i]);
                var mySubInterval = setInterval(function(){
                    i++;
                    if(i === alphabet.length) i = 0;
                    console.log(alphabet[i]);
                }, 1000);
                if(mySubInterval) clearInterval(mySubInterval);
            }
        </script>
    </head>
    <body onload="start();"><div class="div"><button type="button" id="the_button">click me</button></div></body>
</html>
Nathan Chu
  • 635
  • 1
  • 3
  • 19