2

I've never been able to properly use the setTimeout function, so I tried writing a sample script to update a progress bar, but again, it does not work. Instead, the entire program runs before the progress bar is updated to 100%. Would somebody be able to look at this code and tell me what I'm doing wrong?

The code I'm trying to use is from http://digitalbush.com/projects/progress-bar-plugin/

Thanks!

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://digitalbush.com/wp-content/uploads/2007/02/jqueryprogressbar.js" type="text/javascript"></script>
<title>Progress Bar test</title>
</head>
<body>
<style>
    /* progress bar container */
    #progressbar{
        border:1px solid black;
        width:200px;
        height:20px;
        position:relative;
        color:black; 
    }
    /* color bar */
    #progressbar div.progress{
        position:absolute;
        width:0;
        height:100%;
        overflow:hidden;
        background-color:#369;
    }
    /* text on bar */
    #progressbar div.progress .text{
        position:absolute;
        text-align:center;
        color:white;
    }
    /* text off bar */
    #progressbar div.text{
        position:absolute;
        width:100%;
        height:100%;
        text-align:center;
    }
</style>

<div id="progressbar"></div>
<input type='button' value='start' onClick='run()' />

<script>
function run() {
    for (i=0; i<100; i++) {
        setTimeout( function() {
            $("#progressbar").reportprogress(i);
        }, 500);
    }
}
</script>
</body>
</html>
2
  • It's not clear what sort of behavior you expect. How do you know how long it should take for the progressbar to complete? In other words, why is a timeout an appropriate way to show the progress bar in the first place? Commented Oct 6, 2011 at 19:03
  • Well, in this example I was trying to get it to slowly increase from 0 to 100% in say about 10 seconds. Instead, it jumps from 0 to 100% without anything inbetween. Ultimately, I want to implement this in code that involves lots of processing and for loops, to let the user know how far along it is Commented Oct 6, 2011 at 19:09

2 Answers 2

3

setTimeout is not sleep (JavaScript doesn't have a sleep).

As you loop round, you set the function to run in 500ms, then you immediately set it to run again in 500ms, and so on. So effectively, you set it to run 100 times in 500ms, and have set i to 100 before the first time it executes (since it takes a JS engine less then half a second to run that for loop 100 times).

You want something more like this:

var interval, i = 0;
interval = setInterval(function () {
    if (i === 100) {
        clearInterval(interval);
    } else {
        $("#progressbar").reportprogress(i);
        i++;
    }
}, 500);
Sign up to request clarification or add additional context in comments.

Comments

2

The issue is that variable i becomes the part of the closure and, when the function is executed, is already equal to 100.

The code you have currently literally creates a hundred of timeouts referencing the same variable(global i). By the time all of the functions are executed, i equals 100, therefore you report 100 as current progress 100 times.

The proper version should look like that:

function run() {
    var i = 0;
    setTimeout( function updateProgress() {
        $("#progressbar").reportprogress(i++);
        if (i < 100){
            setTimeout(updateProgress, 500);
        }
    }, 500);
}

You could check closures part of javascript garden for explanation and possible other solutions.

1 Comment

Yeah, this does what I wanted. I guess I have a better understanding now of how exactly setTimeout works. I just need to remember that the rest of the script will continue to run before the setTimeout delay triggers. Now I'll see if I can transfer this over to larger program. Thanks!

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.