5

I have a long running Javascript function, that looks like this:

window.myFunction = function() {
    for(var i=0;i<500;i++){
        // calling a function here
        document.getElementbyID('mySpan').innerHTML = "Completed step " + i + "/500"
    }
}

My function calls another synchronous function very often (I used 500 in this example) and while the user waits for the task to complete, i'd like to implement something like a loading bar but I demonstrated it with updating a span in my case here. Is it possible to force a DOM refresh of some sort every time I update my span?

1
  • you have a typo getElementById Commented Sep 25, 2017 at 11:43

2 Answers 2

4

Since scripts run in a single thread in your browser, any method like yours will need to complete before the DOM is updated. What you can do, however, is use an iterative function with a small delay that allows the browser to redraw.

Here's an example...

window.myFunction = function(i) {
    // calling a function here - passing i as a parameter, if needed
    document.getElementById('mySpan').innerHTML = "Completed step " + i + "/500";
    i++;
    if (i <= 500) setTimeout(function() { myFunction(i) }, 1);
}

myFunction(0);
<span id="mySpan"></span>

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

2 Comments

Doesn't an iterative function has a maximum depth and can fail after a certain amount of iterations? Whats the maximum number of iterations I can go through?
In this instance there's no maximum depth. That's only an issue where recursion is involved, and in this case the function dies straight after calling itself. So while it appears to be recursive, it's actually not.
2

You should use a setTimeout method to run it on the event queue rather than run it on the stack. Because you won't see the updates inside a for loop since it runs without a delay. I added a callback to run it after a heavy task.

//Heavy task function
var heavyTask = function(i, callback) {
  setTimeout(function() {
    document.getElementById('mySpan').innerHTML = "Completed step " + i + "/500";

    //Callback to the caller saying the task is finished here and continue on
    /////////////////////
    callback();

  }, 50);
}


var i = 0;

//Call myFunction recursively.
(window.myFunction = function() {
  if (i < 500) {
    heavyTask(i, function() {
      i++;
      window.myFunction();
    });
  }
})();
<span id="mySpan"></span>

2 Comments

What if the function being called takes longer than the interval?
@Archer I updated the answer. Have a look. You should call the callback from the heavy task once the task is completed.

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.