1

Doing some testing of a Jquery loop which calls a function within the loop 3 times. It seems like the function is called each time in the loop, but does NOT execute. At the end of the loop, the function then executes 3 times. Not what I want.

Why does the loadData not execute and append each time it is called? The alerts just tell me that each stage is performed as the loop cycles through.

My ultimate objective is to call a similar function each time until it fills the browser window to the bottom of the screen, then stop. But, with this behaviour, if I put a check in the loop for the condition of filled screen, it will not work since the screen will not fill at all as the loop churns.

Is there a way I can make this work, where a loop calls a function and the function actually executes each time it is called and do what it was designed to do?

Code below:

function loadData() {
  alert('loadData function called');
  $("#load_data").append("test");
}
var x = 0;
while (x < 3) {
  x = x + 1;
  alert('X number is: ' + x);
  loadData();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="load_data"></p>

5
  • 1
    it works as expected. alert in loop, then alert in function, then append text, etc... So where is the Problem? Commented Jun 3, 2018 at 7:49
  • Are you using setTimeout or some asynchronous function in the loop ? Commented Jun 3, 2018 at 7:51
  • There's a difference between the point in time at which the function executes and the point in time at which the browser decides to update the view. Browsers don't repaint until they really have to while JavaScript code is running, and as noted alert() just makes that much more noticeable. Commented Jun 3, 2018 at 7:54
  • @Rami.Q - problem is text does not get appended each time, but only until loop finishes 3 times. Commented Jun 3, 2018 at 9:24
  • @NanditaAroraSharma. No, not using any setTimeout or asynchronous function in the loop. The code is as presented. Commented Jun 3, 2018 at 9:27

1 Answer 1

3

It looks like the rendering doesn't occur until the alert stops blocking and the main thread completes. The test is synchronously appended at the time the line runs in the Javascript, but the HTML the user can see doesn't visually change until the loop is finished.

One possibility would be for loadData to return a Promise that resolves immediately (right after there's been time for the rendering to take place), and for the loop to await each call of loadData, as in the snippet below. But it would be better not to use alert at all - it's very user unfriendly, and blocking (like this) is almost never a good idea.

function loadData() {
  alert('loadData function called');
  $("#load_data").append("test");
  console.log($("#load_data").text());
  return new Promise(resolve => setTimeout(resolve));
}
var x = 0;
(async () => {
  while (x < 3) {
    x = x + 1;
    alert('X number is: ' + x);
    await loadData();
  }
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="load_data"></p>

The same behavior occurs with the native textContent:

const loadDataElm = document.querySelector('#load_data');
function loadData() {
  alert('loadData function called');
  loadDataElm.textContent += 'test';
  console.log(loadDataElm.textContent);
}
var x = 0;
while (x < 3) {
  x = x + 1;
  alert('X number is: ' + x);
  loadData();
  // await loadData();
}
<p id="load_data"></p>

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

1 Comment

Yes, this seems like it could work! I'll have to try this out on an Ajax function which gets data from a database and the loop keeps calling it until the screen is full. The alert functions were just for verification and will be removed. Thank you!

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.