Synchronous Sleep function in Javascript

5.9k Views Asked by At

I want to simulate a progress bar using JS/JQuery, this is my HTML code :

<p id="percentage">0%</p>

I want to go from 0 to 100 and see -Visually- the progress in slow motion, So What I need exactly is a For Loop and a pause function, but unfortunately there is no sleep-like function in Javascript

1st try :

After doing some research, I found the setTimeOut function in Jquery, you can find herein the Javascript code :

for (i = 0; i < 100; i++) { 
    setTimeout(function() {
        $("#percentage").text(i+"%");
    }, 1000);
} 

But unlikely, this won't work, because according to the documentation the setTimeout function is asynchronous, and the execution of the Javascript will continue. That means that there is no pause-like behavior, and the progress bar will go from 0 to 100 after 1000ms instead of going from 0 to 1.

2nd try :

While setTimeout can't solve my problem, I tried to implement my own sleep() function, and here it is :

function sleep(ms){
    var waitTimeInMilliseconds = new Date().getTime() + ms;
    while(new Date().getTime() < waitTimeInMilliseconds ) true;
}

While I was thinking that this is the silver bullet to this scenario -It was a bad Idea, I know-, I was surprised since also this approach didn't solve my problem, and the interface remains Idle during the sleep time, (I cannot click, select or do anything in my HTML page).

How can I solve this problem ?

2

There are 2 best solutions below

0
On BEST ANSWER

You'd probably want something a bit like this using setInterval:

var i = 0;
var intervalId;
intervalId = setInterval(function() {
    $("#pourcentage").text(i+"%");
    if(i >= 100){
        clearInterval(intervalId);
    }
    i++;
}, 1000);

or using setTimeout instead:

var i = 0;
var scheduleNextTimeout; 
scheduleNextTimeout = function(){
    setTimeout(function() {
        $("#pourcentage").text(i+"%");
        if(i < 100){
            scheduleNextTimeout();
        }
        i++;
    }, 1000);
};
scheduleNextTimeout();
0
On

I would suggest the use of a recursive function for this.

function doProgress (startingPercent, interval) {
    var percent = startingPercent++;

    window.setTimeout(function () {
        $('#percentage').text(percent.toString() + '%');

        if (percent < 100) {
            doProgress(percent, interval);
        }
    }, interval);
}