Side navigation
#12325 closed enhancement (wontfix)
Opened August 17, 2012 05:09AM UTC
Closed August 17, 2012 09:07AM UTC
Last modified August 17, 2012 09:23AM UTC
Options parameter for $.when() to provide alternative semantics
| Reported by: | hippietrail | Owned by: | |
|---|---|---|---|
| Priority: | undecided | Milestone: | None |
| Component: | unfiled | Version: | 1.8.0 |
| Keywords: | Cc: | ||
| Blocked by: | Blocking: |
Description
Currently $.when() has only one way of operating:
Wait until all Deferred's have been resolved ''or'' one has been rejected.
But there seem to be use cases for it to operate in other ways.
Some people want:
Wait until all Deferred's have been either resolved or rejected. (stackoverflow), (jquery bugs)
Others want:
Wait until one Deferred has been resolved. (stackoverflow), (stackoverflow)
And one more is:
Wait until all Deferred's have been rejected. (stackoverflow)
Do you see any merit in adding an "options" or "semantics" parameter to $.when() to allow the caller to specify these alternative behaviours? It could be as simple as this:
$.when( d1, d2, d3, {
resolves: 'first',
rejects: 'all'
}).then(
// do stuff
);
(I guess you'd like to see a plugin first, but so far I'm not good enough at jQuery for that. In the meantime I'm interested in what others think of this proposal.)
Attachments (0)
Change History (2)
Changed August 17, 2012 09:07AM UTC by comment:1
| resolution: | → wontfix |
|---|---|
| status: | new → closed |
Changed August 17, 2012 09:23AM UTC by comment:2
Ah, also, if you need more advanced/flexible synchros. You're probably better off with something like fence that'll abort non-completed ajax requests in case of rejection. See https://github.com/jaubourg/fence/blob/master/doc/intro.md#introduction-to-fence
Again, I still have to find time to write the damn API doc.
There are several problems with this approach.
The first, most obvious, one is that you effectively forbid the use of
whenwith an object that contains properties named resolves or rejects (whenwill promote such an object to a resolved Promise with the object itself as the resolve value).So, if you want this new functionality, put it in a new helper.
The second one is a matter of semantics and predictability. I'll take your first example here: waiting when all deferred are either resolved or rejected.
How do you differentiate between resolve and rejection values when they are in the same arguments list?
$.whenResolvedOrRejected( $.Deferred().resolveWith( null, [ 1, 2, 3 ] ), $.Deferred().rejectWith( null, [ 4, 5, 6 ] ) ).done(function( resolveValues, rejectValues ) { // How do I know what was resolved and what was rejected? });The only solution is to keep track of Deferreds in local variables:
var defer1 = $.Deferred().resolveWith( null, [ 1, 2, 3 ] ), defer2 = $.Deferred().rejectWith( null, [ 4, 5, 6 ] ); $.whenResolvedOrRejected( defer1, defer2 ).done(function( resolveValues, rejectValues ) { defer1.state() === "resolved"; defer2.state() === "rejected"; });That's simply an horrible approach.
To me, it's a typical case of Promise "re-routing":
function resolveAlways( promise ) { return promise.then(function() { return Deferred.resolveWith( this, [ "resolved" ].concat( arguments ); }, function() { return Deferred.resolveWith( this, [ "rejected" ].concat( arguments ); }); } $.whenResolvedOrRejected( resolveAlways( $.Deferred().resolveWith( null, [ 1, 2, 3 ] ) ), resolveAlways( $.Deferred().rejectWith( null, [ 4, 5, 6 ] ) ) ).done(function( resolveValues, rejectValues ) { resolveValues == [ "resolved", 1, 2, 3 ]; rejectValues == [ "rejected", 4, 5, 6 ]; });(I know
argumentsneed to transformed into an array, but you get the idea)Anyway,
$.whenis equivalent to a logicalAND. I think that, if people need other kinds of operators, they should create new helpers, not mess with$.whento the point it doesn't make sense anymore.I'd be glad to add such helpers into ajaxHooks ( https://github.com/jaubourg/ajaxHooks ), since adding new Promise helpers was my intention all along... except I just can't find the time to even maintain what's already in there :(