10

I wanna synchronized functions just like jQuery's $.ajax({ .., async: false, .. });.

function A() { lalala .. };
function B() { dadada .. };
function C() { .. };

, those all including some effect like fadeIn, Out, slide... etc.

However I just found if those functions called like below..

A();
B();
C();

All effect start at almost same time. In my understanding, this happens because the function called synchronously but it doesn't mean that function B() started after function A() was completely finished.. right?

Then, how can I make those functions work in order?

I found a way use callback function but it's not enough for me..

GatesPlan
  • 465
  • 1
  • 4
  • 17

3 Answers3

16

Have a look at using jQuery $.Deferred();

That can allow you to run each function in sequence, one waiting after the other. For example:

var a = function() {
    var defer = $.Deferred();

    console.log('a() called');

    setTimeout(function() {
        defer.resolve(); // When this fires, the code in a().then(/..../); is executed.
    }, 5000);

    return defer;
};

var b = function() {
    var defer = $.Deferred();

    console.log('b() called');

    setTimeout(function () {
        defer.resolve();
    }, 5000);

    return defer;
};

var c = function() {
    var defer = $.Deferred();

    console.log('c() called');

    setTimeout(function () {
        defer.resolve();
    }, 5000);

    return defer;
};

a().then(b).then(c);

Using defer.resolve(); means you can control when the function yields execution to the next function.

Spoeken
  • 2,549
  • 2
  • 28
  • 40
Jason Evans
  • 28,906
  • 14
  • 90
  • 154
  • To the editor who made a change to my post - "Links are always nice :)" I did put the link to deferred in my first attempt, but the text editor flagged up saying "Links to jQuery something or other aren't allowed." So I left it out at the time. I like links too :) – Jason Evans Nov 19 '14 at 09:17
  • 1
    SOF actually hides that last line that really brings this all together. the a(0).then(b).then(c);. This comment exists to help the next guy who didnt notice the scroll bar to the left :D – Morgeth888 Apr 25 '17 at 20:44
3

You have indeed specified three synchronous functions, meaning B will only trigger when A has finished.

However, doing asynchronous tasks like starting an animation won't stop A from completing, so it appears that B isn't waiting until completion.

Read about jQuery Deferreds. Deferreds is a design pattern, so it's not specific to jQuery, however they have a great implementation.

function methodA () {
    var dfd = $.Deferred();

    console.log('Start A');

    // Perform async action, like an animation or AJAX call
    $('#el').slideOut(2000, function () {
        // This callback executes when animation is done.
        console.log('End A');
        dfd.resolve();
    });

    // Return unchangeable version of deferred.
    return dfd.promise();
};

function methodB () {
    console.log('Start B');
};

methodA().then(methodB);
1

I suppose that each function makes some ajax request or animation

function A() {
  return $.ajax(....);
  // or
  // return $('#animate').animate({ width: 100 }, 1000 ).promise();
  // or
  // var def = $.Defered();
  // in async function def.resolve();
  // return def.promise();
}

function B() {
  return $.ajax(....); 
  // or 
  // return $('#animate').animate({ width: 200 }, 3000 ).promise();
  // var def = $.Defered();
  // in async function def.resolve();
  // return def.promise();
}

function C() {
  return $.ajax(....);
  // or
  // return $('#animate').animate({ width: 300 }, 1000 ).promise();
  // var def = $.Defered();
  // in async function def.resolve();
  // return def.promise();
}

$.when(A(), B(), C(), function (aRes, bRes, cRes) {
})

//C().then(B()).then(A()).done(function () {
//  console.log('DONE');  
//});

For a more detailed answer please explain what your functions do

Oleksandr T.
  • 76,493
  • 17
  • 173
  • 144