0

I have a 2 JS files in my program, and one is calling a function in another file, and passing two arguments to it. No issues there - the loop on the 2nd file works as expected - until it gets to terminating. I'm doing something similar in another part of my app with no issues at all.

Code from file 1 (this loop is called from an event on the page - it returns a function so I can include the arguments without calling the function):

let loopStat = false;

let j = 0;

const sleep = (milliseconds) => {
    return new Promise(resolve => setInterval(resolve, milliseconds))
  }

const callLoop = (item) => {
    
        return function() {
            loopStat = !loopStat;
    
            loopFunc(loopStat, item);
        }
    }

const loopFunc = async (z, item) => {

        console.log('before loop', z);

        while (z == true) {
            
            console.log('inside loop', z);
  
            j++;
            
            console.log(j);

            await sleep(1000);
        }
     }
     
var button = document.getElementById('button')
button.addEventListener("click", callLoop(button));
<div id="parent">
  <button id="button">Loop</button>
</div>

Obviously "z" is used to terminate the loop in this function. I included the "console.log" bits to show what "z" is at different points. When the button is clicked again, it toggles the "loopStat" variable to false, calls the function again and sends that argument along. The weird thing is, the new argument is being sent to the function(as shown in the 'before loop' console.log), but inside the loop it changes "z" back to true, as shown in the 'inside loop' console.log.

I think it's also worth mentioning that the variables "z" and "loopStat" are not used anywhere else in the app.

I'm expecting the solution to be something obvious, and I'm suspecting it's a scope issue.

10
  • Can you rewrite this code as some embedded code that we can run here? Commented Feb 13, 2020 at 1:12
  • If z is not true at the start of the while loop in loopFunc, the while-loop won't execute. Ok. But if z is true, nothing in the loop changes the value of z, so it will never become false and the loop will never terminate. (and … you never need (something == true) -- that can always be rewritten as (something) e.g. if (outcome == true) becomes if (outcome)) Commented Feb 13, 2020 at 1:17
  • z is a local variable that contains the original value of loopStat when it was called. Changing loopStat in an event handler will not change the value of z. Commented Feb 13, 2020 at 1:21
  • did you mean to have setInterval be setTimeout instead? setInterval doesn't make a lot of sense for how it has been implemented. Commented Feb 13, 2020 at 2:09
  • @Jhecht - sorry, I just updated everything again, and it's now replicating the issues I had before. Please check it out and run the snippet now. Thanks. Commented Feb 13, 2020 at 2:13

1 Answer 1

1

I guess I get to answer my own question, since no one else got it.

It turns out that the variable used as the condition for the loop needs to be DECLARED outside of the scope of the loop, and even outside of the function containing it.

var condition = false;

const callLoop = (z) => {

    //If this variable is going to be the condition for the loop, it has to
    //be declared outside of the function containing the loop.  You can't
    //just pass the argument containing the value as the condition.  
    //Obviously, you could also just use "x" as the condition, in this case. 
    condition = z;
    var j = 0;

    while (condition === true) {
        j++;
    }
}

var x = false;
const toggleLoop = () => {
    x = !x;
    callLoop(x);
}
Sign up to request clarification or add additional context in comments.

3 Comments

This was the point of my comment above -- you can't test the parameter variable, you have to test a global variable.
You are right about that, but changing the argument passed to the function did change the value of z(as shown in the console.log notes). That's why I was confused the way your original answer was worded, because changing loopStat did change z, just not in the condition for the loop. You led me in the right direction, though.
Of course, each time you call it with a different value, the function has a different z. But it doesn't change during the loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.