#12348 closed bug (worksforme)
$.when doesn't work as-documented?
Reported by: | cowboy | Owned by: | |
---|---|---|---|
Priority: | low | Milestone: | None |
Component: | ajax | Version: | 1.8.0 |
Keywords: | Cc: | jaubourg | |
Blocked by: | Blocking: |
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 (5)
comment:1 Changed 10 years ago by
comment:2 Changed 10 years ago by
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 years ago by
$.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 years ago by
Component: | unfiled → ajax |
---|---|
Keywords: | needsdocs added |
Priority: | undecided → low |
Resolution: | → worksforme |
Status: | new → closed |
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 10 years ago by
Keywords: | needsdocs removed |
---|
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
.