If I have a function that sometimes returns a deferred object but sometimes a non-deferred object. How can I tell which one it is?
-
"Type checking" implies other aspects :) – Jun 09 '12 at 22:39
-
nice one, had the same issue here – Matías Cánepa Jan 20 '14 at 21:11
3 Answers
Depending on your use case, you could also use jQuery.when
[1]:
If a single argument is passed to
jQuery.when
and it is not a Deferred, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.
With jQuery.when
you can treat your mysterious object always as deferred:
// x could be a deferred object or an immediate result
var x = getMysteriousObject();
// success will be called when x is a deferred object and has been resolved
// or when x is an immediate result
jQuery.when( x ).then( success, error );

- 1,793
- 14
- 13
-
won't your 'success' handler potentially have different arguments passed to it - depending on if the object was deferred or not? In which case you're still going to have to use duck-typing like what's suggested below. – backdesk Mar 03 '14 at 13:57
-
1@Crungmungus: "If a single argument is passed to jQuery.when and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately. The doneCallbacks are passed the original argument." – Dmitry Minkovsky May 12 '14 at 19:15
-
2`$.when( { testing: 123 } ).done(function( x ) { alert( x.testing ); // Alerts "123" }); – Dmitry Minkovsky May 12 '14 at 19:16
Since jQuery Deferreds are created by copying the methods of a hidden object instead of calling the new operator on a function, you cannot proof that the object is indeed an instance of jQuery.Deferred. I think you're gonna need to go with Duck-Typing:
"When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck." – James Whitcomb Riley
Depending on what objects might otherwise be returned (what properties must be expected), check if particular properties / methods are present:
var x = getMysteriousObject();
if (x.promise) {
// Deferred
} else {
// Not a deferred
}
You can detailed this check if required:
if ($.isFunction(x.promise)) {
// Deferred
}
or (to distinguish between Deferred objects and other implementations of the Promise interface)
if (x.promise && x.resolve) {
// Deferred
}

- 26,516
- 9
- 93
- 110
-
Ok, then I think duck-typing is the best way to go. Was worrying about getting a quail instead of a duck. Now think it's not that important. Many thanks! – WawaBrother Jun 11 '12 at 20:14
Inspired by Niko's answer, I created another implementation that would check if an object is a deferred based on the name of it's properties but also on the content of those properties. I had to do so since an other object of mine had a property named promise.
if (typeof value.resolve !== "function") {
return false;
}
return String(value.resolve) === String($.Deferred().resolve);

- 1
- 1

- 5,178
- 14
- 52
- 78