Side navigation
#12348 closed bug (worksforme)
Opened August 19, 2012 07:01PM UTC
Closed August 20, 2012 11:48PM UTC
Last modified October 15, 2012 09:51PM UTC
$.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 ]
Attachments (0)
Change History (5)
Changed August 19, 2012 07:10PM UTC by comment:1
Changed August 20, 2012 12:40AM UTC by comment:2
cc: | → jaubourg |
---|
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.
Changed August 20, 2012 08:03AM UTC by comment:3
$.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.
Changed August 20, 2012 11:48PM UTC by comment:4
component: | unfiled → ajax |
---|---|
keywords: | → needsdocs |
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.
Changed October 15, 2012 09:51PM UTC by comment:5
keywords: | needsdocs |
---|
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
.