Bug Tracker

Modify

Ticket #12348 (closed bug: worksforme)

Opened 10 months ago

Last modified 8 months ago

$.when doesn't work as-documented?

Reported by: cowboy Owned by:
Priority: low Milestone: None
Component: ajax Version: 1.8.0
Keywords: Cc: jaubourg
Blocking: Blocked by:

Description

I see this text and example  the docs:

If a single Deferred is passed to jQuery.when, its Promise object (a subset of the Deferred methods) is returned by the method. Additional methods of the Promise object can be called to attach callbacks, such as deferred.then. When the Deferred is resolved or rejected, usually by the code that created the Deferred originally, the appropriate callbacks will be called. For example, the jqXHR object returned by jQuery.ajax is a Deferred and can be used this way:

$.when( $.ajax("test.aspx") ).then(function(ajaxArgs){ 
     alert(ajaxArgs[1]); /* ajaxArgs is [ "success", statusText, jqXHR ] */
});

The thing is, when I pass a single jqXHR into $.when like in  this fiddle:

​$.when( $.ajax(​"/echo/json/?a=1") ).then(function(ajaxArgs) {
    console.log(arguments.length, arguments);
});​​​​​​​​​​​

It logs 3 [Object, "success", Object], not [1 [Array]] Like I would expect, based on the example in the documentation. It seems like the array that the jqHXR is resolved with isn't passed into the .then callback as an array, but is instead applied onto the callback using .apply.

Also, the array in the example, [ "success", statusText, jqXHR ] is confusing. Maybe something more like [ response, statusText, jqXHR ]

Change History

comment:1 Changed 10 months ago by cowboy

Part of the problem, that I see, is that because $.when is too smart for its own good, it sees a single jqXHR as a single Deferred.

And per the very first line in the docs, "If a single Deferred is passed to jQuery.when, its Promise object (a subset of the Deferred methods) is returned by the method, " it's assuming (incorrectly) that the single jqXHR is a Deferred wrapper around other deferreds, and thus applies the array the jqXHR is resolved with.

Basically, you should never pass in a single jqXHR into $.when.

comment:2 Changed 10 months ago by dmethvin

  • Cc jaubourg added

You don't really need $.when for a single promise/deferred. I agree the example doesn't look right. Perhaps we need to included better reasoning there about why a single promise is treated specially.

comment:3 Changed 10 months ago by jaubourg

$.when is simply idempotent:

$.when( 1, 2, 3 ).done(function( a, b, c ) {
    a === 1;
    b === 2;
    c === 3;
});

$.when( $.when( $.when( 1, 2, 3 ) ) ).done(function( a, b, c ) {
    a === 1;
    b === 2;
    c === 3;
});

If it was to force every value into an array as was suggested in #10811, you would end up with:

$.when( $.when( $.when( 1, 2, 3 ) ) ).done(function( val ) {
    val = [ [ [ 1 ], [ 2 ], [ 3 ] ] ];
});

The single argument "passthru" ensures using $.when doesn't turn into a dereferencing nightmare.

I don't know why the doc is so, so wrong btw.

comment:4 Changed 10 months ago by dmethvin

  • Keywords needsdocs added
  • Priority changed from undecided to low
  • Status changed from new to closed
  • Component changed from unfiled to ajax
  • Resolution set to worksforme

Here's the results of that example, slightly modified:  http://jsfiddle.net/SAZY3/

But the description is fine, the example is just wrong.

comment:5 Changed 8 months ago by mikesherov

  • Keywords needsdocs removed

Please follow the  bug reporting guidlines and use  jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.