How can I determine if a jQuery object is deferred?

后端 未结 3 1795
醉梦人生
醉梦人生 2020-12-11 00:21

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?

相关标签:
3条回答
  • 2020-12-11 00:50

    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
    }
    
    0 讨论(0)
  • 2020-12-11 00:57

    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] http://api.jquery.com/jQuery.when/

    0 讨论(0)
  • 2020-12-11 00:57

    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);
    
    0 讨论(0)
提交回复
热议问题