0

I'm using JQuery v2.0.0

How do I make these functions run in top to bottom order instead of an asynchrous-like effect or order, meaning don't let the function "foo2()" run before the function "foo1()" is done first.

foo1();

$.when( foo2() )
    .done(function() { $('#test').dialog('close');  foo3(); })
    .fail(function() { alert('You have a problem!!');  foo3(); });

Thanks...

fletchsod
  • 3,560
  • 7
  • 39
  • 65
  • 2
    Use .done on foo1(), assuming foo1() returns a promise object. also, your $.when is not necessary, you can do foo2().done, also assuming foo2() returns a promise object. If neither return promise objects, then your code won't work. – Kevin B Nov 20 '13 at 16:47

1 Answers1

2

Assuming foo1 looks something like this:

function foo1() {
    var promise = $.Deferred();
    $.ajax({...}).done(function() { promise.resolve(); })
        .fail(function() { promise.reject(); });
    return promise;
}

You can do this:

foo1().done(function() {
    $.when( foo2() )
        .done(function() { $('#test').dialog('close');  foo3(); })
        .fail(function() { alert('You have a problem!!');  foo3(); });
});

...or as @Kevin B mentioned, like this:

foo1().done(function() {
    foo2()
        .done(function() { $('#test').dialog('close');  foo3(); })
        .fail(function() { alert('You have a problem!!');  foo3(); });
});

...but as comments point out, a better implementation of foo1 would look like this, which you can do as long as foo1 doesn't need to do any custom work during done, fail, or always.

function foo1() {
    return $.ajax({...});
}

Otherwise, if foo1 is not async in any way, it will always complete first.

danludwig
  • 46,965
  • 25
  • 159
  • 237
  • Two questions. [1] Is foo1() suppose to return "promise.promise()" insetad of "promise"?? [2] foo1() have no $.ajax but I can implement $.Deferred() (or promise) but how would that works without AJAX? – fletchsod Nov 20 '13 at 17:11
  • 1
    @fletchsod "if foo1 is not async in any way, it will always complete first." – A. Wolff Nov 20 '13 at 17:17
  • 3
    `function foo1() { return $.ajax() }` and `foo2().done(...)` to simplify code – A. Wolff Nov 20 '13 at 17:20
  • 1
    To clarify what A. Wolff said: `$.ajax` is already a deferred, so there is no reason to wrap it in another deferred. – jcbelanger Nov 20 '13 at 17:24
  • 2
    Also, the `promise` variable in `foo1`. is really a deferred and not a promise. The difference between the two is deferreds can be canceled and promises cannot (think read-only). You can create a read-only version by calling the `.promise()` method on a deferred. – jcbelanger Nov 20 '13 at 17:27
  • Awesome!! Many thanks to "A Wolff", "cereal77killer" and "Kevin B" for damn-good & piece-of-cake clarifications. The JQuery Deferred is really confusing on many different JQuery versions. – fletchsod Nov 20 '13 at 17:37
  • 1
    Also, the accepted answer is using nested callbacks to control the sequence. While this works, it is missing one of the major benefits of using deferreds: to AVOID callback hell. – jcbelanger Nov 20 '13 at 18:10