0

I want to know why the following code does not wait for an animation to finish before starting the next animation in the loop.

For some reason all the elements created by the loop are displayed at once and faded in simultaneously. From the code, I would expect that the first element would finish fading in before the first iteration of the loop finishes then the second iteration of the 'for' loop would fade in the next element and so on..

I do not want to use callbacks before this creates messy code and also I want to use a loop which will use dynamic data -- the number of animations will vary.

<div id="container"></div>

<script>
var data = [1,2,3,4]; 

for(var i = 0; i < data.length; i++){
    $("#container").append("<h1>"+data[i]+"</h1>").hide().show("fade",2000);
    $("#container").promise().done(function(){console.log('sweet');});
}
</script>
Trevor
  • 139
  • 1
  • 10
  • 1
    I don't think you can achive that with loop. Use Promise chain and some recursive function with counter. 1st Promise on resolving returns second Promise and so on – Maxim Shoustin Dec 15 '16 at 22:08
  • Sorry, don't understand what you mean. Can you provide code example? I've scoured the internet but can't find anything describing loops and use of promises that can be used with jquery effects.. – Trevor Dec 15 '16 at 22:36

1 Answers1

2

Promises do not magically halt your for loop, all they do is provide a way to chain callbacks. You were doing all your animations at once, and waited for them concurrently to finish. To get them in sequence, you can use

<div id="container"></div>
<script>
[1,2,3,4].reduce(function(prev, d, i) {
    return prev.then(function() {
        console.log('start', i)
        return $("<h1/>", {text: d})
        .appendTo("#container")
        .hide().show("fade",2000) // I assume you meant to animate the h1, not the container
        .promise();
    }).then(function() {
        console.log('sweet! end', i);
    });
}, $.when());
</script>
Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks a lot, work exactly the way I want. Would it be possible to explain: – Trevor Dec 16 '16 at 01:33
  • Thanks a lot, work exactly the way I want. Would it be possible to explain: 1) what this line is doing "return prev.then(function() {" and 2) what the "$.when()" part is doing (I thought this was for initial value)? – Trevor Dec 16 '16 at 01:35
  • 1
    Yes, `$.when()` is the initial value - a promise that is immediately fulfilled with `undefined`. `return prev.then(…)` chains the callback function on the previous promise to be executed when it is done, and returns a new promise (that will wait for the result of the callback, the returned `.promise()`) to be used as `prev` in the next iteration. – Bergi Dec 16 '16 at 09:46
  • Is there a reason you used the 'reduce' method instead of a 'for' loop? can this be accomplished in a 'for' loop as well? i hear that 'reduce' has better performance but i find 'for' loop easier to read the code... if you could provide a 'for' loop example that would be really cool.. but already greaful for your existing solution!! thanks – Trevor Dec 16 '16 at 18:01
  • 1
    It's quite the opposite - `for` has better perf, but I find `reduce` easier to read :-) It's basically starting with the initial value (second parameter) and then calling the function on this accumulator (the "previous result") for every array item. If you want to rewrite it to a loop, beware of the [scope issues](http://stackoverflow.com/q/750486/1048572). – Bergi Dec 16 '16 at 23:32
  • 1
    @user1504519, the [reduce pattern is explained in SO documentation](http://stackoverflow.com/documentation/javascript/231/promises/5917/reduce-an-array-to-chained-promises#t=201612171244341259699). – Roamer-1888 Dec 17 '16 at 13:03
  • Thanks @Bergi and Roamer-1888. I'm just finishing up reading a piece on Promises and Deferreds which I'm finding really helpful (https://flaviocopes.com/blog/deferreds-and-promises-in-javascript) -- next I'm going to run through the SO reduce doc and try to further understand bergi's example. All new to me but I think both concepts will be very valuable. Cheers – Trevor Dec 18 '16 at 16:49