3

Imagine I have X, Y and Z functions, all returning promises and ready to chain. What I want to do is to notify about the progress after they are complete and handle error. What is better to write and why (what are the consequences):

A.

function my_func(index, size){
    return X
        .then(Y)
        .then(Z)
        .then(
           function(data){
               var dfd = new $.Deferred();
               dfd.notify("progress", index / size, 'OK');
               dfd.resolve(data);
               return dfd.promise();
           },
           function(){
               return handleError(arguments, size, index);
           }
        );
}

or

B.

function my_func(index, size){
    var dfd = new $.Deferred();
    X
    .then(Y)
    .then(Z)
    .then(
        function(data){
            dfd.notify("progress", index / size, 'OK');
            dfd.resolve(data);
        },
        function(){
            return handleError(arguments, size, index);
        }
    )
    return dfd.promise();
}

Also, what is the difference between:

X.then(Y).then(Z);

and:

$.when(X).then(Y).than(Z);

If $.when part is unnecessary, why doeas it exist in jQuery at all?

mnowotka
  • 16,430
  • 18
  • 88
  • 134

2 Answers2

0

The latter is unnecessary. It's just extra cruft. $.when is useful for converting values to promises and for aggregation.

Here is an average $.when use case:

$.when($.get(...),$.get(...)).then(function(firstResult,secondResult){
     // access both results here
}); 

You can use both results here, both have finished.

As for the first question - basically B. The first option is the deferred anti pattern and is better avoided. See the link to it question on why.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • Thank for this explanation, what about the first part of my question? – mnowotka Jul 10 '14 at 09:59
  • Agreeing with @BenjaminGruenbaum here, the 2nd approach seems way cleaner, as the `my_func` function properly wraps what is happening inside. But... all in all, I think you are under the wrong assumption that the `.then()` chaining will make things happen in that order, that only if `Y` is resolved, that then `Z` will happen. This is not the case, all the `.then()`s in both cases happen when `X` resolves. I too was under that impression, but see this JSFiddle (press the 2nd button): http://jsfiddle.net/vH84q/1/ (EDIT: Have the browser console open to see what's happening.) – UweB Jul 10 '14 at 10:19
0

The main difference would be that you are relying on X to be an object that has the method then. Passing a non Deferred/promise object to $.when will treat it as a resolved Deferred, which personally I would prefer as it makes the coupling between the functions more loose.

UweB
  • 4,080
  • 2
  • 16
  • 28
  • A more correct term might be "fulfilled", it will treat it as a fulfilled deferred. – Benjamin Gruenbaum Jul 10 '14 at 09:36
  • I agree, but I actually quoted from the jQuery API documentation ;) "...it will be treated as a resolved Deferred...", see http://api.jquery.com/jQuery.when/ – UweB Jul 10 '14 at 09:37
  • The same comment goes here - I appreciate explanation of usage of `when` but to me the first part of my question is more important :) – mnowotka Jul 10 '14 at 10:00