1

I have a html file with a single button on it

<!DOCTYPE html>
<html>    <body>
<p>Click the button to list all the items in the array.</p>

<button onclick = "numbers.forEach(myFunction)" >Try it</button>

<p id="demo"></p>
</body>     
</html>

I also have the Javascript file containing the onclick function for the .forEach method.
When the button is clicked the I'd like to go through an array, looping through each instance of element in the array.

For every element in this array, I'd like to print out its index and value with a timer afterward that waits a second to display the next permutation.

demoP = document.getElementById("demo");
var numbers = [];

var random = Math.floor(Math.random() * 4) + 1;

numbers.push(random);

function myFunction(item, index) {
  random = Math.floor(Math.random() * 4) + 1;
  numbers.push(random);
  demoP.innerHTML = demoP.innerHTML + "numbers[" + index + "]: " + item + "<br>"; 
  //demoP.innerHTML = demoP.innerHTML + "<br>" //add magic spacing between permutation
  sleep(100);
  //switch to this and see how slow?
  //sleep(1000);
}

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

What I'd like the result to show when the user clicks the button is:

numbers[0] = 4
//waits a second and adds a <br> here to separate
numbers[0] = 4
numbers[1] = 2
//waits a second and adds a <br> here
numbers[0] = 4
numbers[1] = 2
numbers[2] = 3

and so on.

Currently the code outputs at least twice as many elements, and the sleep() seems to be lasting way longer than it should.

3
  • 4
    Please don't try to add a sleep function. Instead learn how to do asyc calls through something like setTimeout or setInterval. Also consider using console.log to track your code as it runs. And since you are changing the array numbers while doing a forEach you are asking for problems. And doing a forEach within the DOM element onclick attribute is not the best way to go. Have onclick call a function and do the forEach in that function. Commented Dec 8, 2017 at 23:05
  • @Intervalia I was having problems with the amount of times its intervaling, so instead of using the 'setTimeout' or 'setInterval' I created a 'sleep()' to test it. Commented Dec 8, 2017 at 23:08
  • @Jamin I made a mistake in my answer. Please read the new updated one. Sorry! Commented Dec 8, 2017 at 23:28

1 Answer 1

4

Apart from the hideous sleep function. You are using myFunction as the callback of forEach, and in myFunction, you are pushing new elements to numbers which is the same array you are calling forEach on.

forEach won't call the callback on the newly pushed items while still looping the array. But by the end of the loop, the items in the array will be doubled. As according to MDN:

The range of elements processed by forEach() is set before the first invocation of callback. Elements that are appended to the array after the call to forEach() begins will not be visited by callback.

If the array contains N elements, then when a click happens, N elements will be shown, and myFunction will push N other elements, and when the next click happen 2N elements will be shown this time, ...

So after each click, the elements in the array will be doubled.

Sign up to request clarification or add additional context in comments.

Comments

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.