peace_love
peace_love

Reputation: 6461

How can I make multiple timeouts behind one another?

I want to show three messages behind one another always with 1 sec delay:

request.upload.addEventListener('progress',function(e){
    setTimeout(function() {
        $form.find('.progress-bar').width(percent+'%').html("first message");
    }, 1000);
    setTimeout(function() {
        $form.find('.progress-bar').width(percent+'%').html("second message");
    }, 1000);
    setTimeout(function() {
        $form.find('.progress-bar').width(percent+'%').html("third message");
    }, 1000);
}

But I on my screen it displays only "third message".

Upvotes: 1

Views: 90

Answers (2)

GMchris
GMchris

Reputation: 5648

Put each timeout inside the previous one, or better yet, use setInterval!

Something like this is much more manageable:

var messages = ['first', 'second', 'third'];
var index = 0;
var interval = setInterval(function(){
  if (index >= messages.length) {
    clearInterval(interval); 
  }
  $form.find('.progress-bar').width(percent+'%').html(messages[index]);
  index++;
}, 1000);

setInterval works similar to setTimeout, except that it repeats the callback method instead of calling it once. The one thing to keep in mind is that you need to clear the interval otherwise it will run forever.

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074198

Just use longer delays on the second two, perhaps 1000, 2000, and then 3000.

Example:

var $form = $("form");
$("input").on("click", function(e){
    var percent = 50; // dummy var
    setTimeout(function() {
        $form.find('.progress-bar').width(percent+'%').html("first message");
    }, 1000);
    setTimeout(function() {
        $form.find('.progress-bar').width(percent+'%').html("second message");
    }, 2000);
    setTimeout(function() {
        $form.find('.progress-bar').width(percent+'%').html("third message");
    }, 3000);
});
.progress-bar {
  display: inline-block;
}
<input type="button" value="Click Me">
<form>
  <div class="progress-bar"></div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

That said, whenver you find yourself repeating the exact same code with just a small variation, it's an opportunity to refactor. For instance:

["first message", "second message", "third message"].forEach(function(msg, index) {
    setTimeout(function() {
        $form.find('.progress-bar').width(percent+'%').html(msg);
    }, 1000 * (index + 1));
});

Note we're using the index (0, 1, 2) plus one to multiply the timeout, so they appear successively.

Example:

var $form = $("form");
$("input").on("click", function(e){
    var percent = 50; // dummy var
    ["first message", "second message", "third message"].forEach(function(msg, index) {
        setTimeout(function() {
            $form.find('.progress-bar').width(percent+'%').html(msg);
        }, 1000 * (index + 1));
    });
});
.progress-bar {
  display: inline-block;
}
<input type="button" value="Click Me">
<form>
  <div class="progress-bar"></div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Upvotes: 2

Related Questions