1
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("#a").hide(1000);
    $("#b").hide(1000);
    $("#c").hide(1000);

});
</script>
</head>
<body>

<p id="a">Paragraph 1</p>
<p id="b">Paragraph 2</p>
<p id="c">Paragraph 3</p>


</body>
</html>

Javascript is single threaded, so I think functions are executed one by one. But in the sample above, it seems the three paragraphs start the hide animation simultaneously and ended at the same time, as if there are three threads each running one distinct animation. why are the animations not run one by one ?

CDT
  • 10,165
  • 18
  • 66
  • 97
  • 1
    http://stackoverflow.com/questions/1594077/jquery-synchronous-animation maybe this question helps – Ishikawa Yoshi Apr 01 '15 at 12:13
  • They technically are ran in order but they are designed to be non blocking by adding creating a timer and callback function. An easy way to test this is to debug the code and step through each line. You will see each one executing one after another – heymega Apr 01 '15 at 12:14
  • 1
    __Synchronous__ and __single-threaded__ are not the same thing. – Evan Davis Apr 01 '15 at 12:20

3 Answers3

2

It think it is related to this part of jquery

jQuery.timers = [];
jQuery.fx.tick = function() {
    var timer,
        i = 0,
        timers = jQuery.timers;

    fxNow = jQuery.now();

    for ( ; i < timers.length; i++ ) {
        timer = timers[ i ];
        // Checks the timer has not already been removed
        if ( !timer() && timers[ i ] === timer ) {
            timers.splice( i--, 1 );
        }
    }

    if ( !timers.length ) {
        jQuery.fx.stop();
    }
    fxNow = undefined;
};

jQuery.fx.timer = function( timer ) {
    jQuery.timers.push( timer );
    if ( timer() ) {
        jQuery.fx.start();
    } else {
        jQuery.timers.pop();
    }
};

jQuery.fx.interval = 13;

jQuery.fx.start = function() {
    if ( !timerId ) {
        timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
    }
};

jQuery.fx.stop = function() {
    clearInterval( timerId );
    timerId = null;
};

jQuery.fx.speeds = {
    slow: 600,
    fast: 200,
    // Default speed
    _default: 400
};

As you can notice there is

setInterval( jQuery.fx.tick, jQuery.fx.interval );

that is non "blocking" js

Tien Nguyen
  • 599
  • 4
  • 13
1

There are not really simultaneous. Starting an animation does not block the execution of your code. They start one after the others but they run "almost" simultaneously. jQuery animations are in fact similar to setInterval, They update the opacity each X milliseconds. but between those X ms code is running. and your animations are starting between this small amount of time.

If you don't want them to be simultaneous you should start them in the callback of the previous one.

Here is the code to make them run one after the other :

$(".a").hide(1000, function() {
   $(".b").hide(1000, function() {
      ....

If you want to use a async library to make your code cleaner (it would be dirty to do it for 10 elements) you can use async https://github.com/caolan/async

async.eachSeries([$(".a"), $(".b"), $(".c")], function(elem, callback) {
   elem.hide(1000, callback);
});
DARK_DUCK
  • 1,727
  • 2
  • 12
  • 22
1

The jQuery animation effects are all non-blocking, which is most often what you want. (The rest of your code shouldn't come to a halt because you're running a long animation)

If you want sequential animation, you can use the callbacks:

$('#a').hide(1000, function() {
   $('#b').hide(1000, fn...);
});

If you're animating on the same object, jQuery uses a queue internally, so there's no need to use callbacks, i.e. $('#a).hide(1000).show(1000) won't try to both hide and show the object at the same time.

David Hedlund
  • 128,221
  • 31
  • 203
  • 222