Bug Tracker

Modify

Ticket #8067 (closed bug: wontfix)

Opened 3 years ago

Last modified 3 years ago

If $.when() receives an object that has a method named "promise", it assumes the object is observable

Reported by: rmurphey Owned by: rmurphey
Priority: low Milestone: 1.next
Component: core Version: 1.5rc1
Keywords: Cc:
Blocking: Blocked by:

Description

Change History

comment:1 Changed 3 years ago by rmurphey

If the object has a promise method, that doesn't mean that what it returns is a promise (having, at least, a then method).

Last edited 3 years ago by rmurphey (previous) (diff)

comment:2 Changed 3 years ago by jitter

  • Component changed from unfiled to core

comment:3 Changed 3 years ago by jitter

  • Owner set to jaubourg
  • Status changed from new to assigned

comment:4 follow-up: ↓ 7 Changed 3 years ago by jaubourg

Testing for then on the returned object doesn't ensure it is a promise either.

 http://jsfiddle.net/9fuHZ/

Design by convention has its limits and no matter how complicated the test becomes, you always have ways around it.

Last edited 3 years ago by jaubourg (previous) (diff)

comment:5 Changed 3 years ago by jitter

  • Owner changed from jaubourg to rmurphey
  • Status changed from assigned to pending

comment:6 Changed 3 years ago by jaubourg

And I'm not gifted with jsfiddle:  http://jsfiddle.net/9fuHZ/7/

comment:7 in reply to: ↑ 4 ; follow-up: ↓ 9 Changed 3 years ago by rmurphey

  • Status changed from pending to new

Replying to jaubourg:

Testing for then on the returned object doesn't ensure it is a promise either.

 http://jsfiddle.net/9fuHZ/

Design by convention has its limits and no matter how complicated the test becomes, you always have ways around it.

As Dave Methvin pointed out to me in the IRC channel, if we don't know what the promise method on the object passed to $.when does, then we probably don't want to run it to see what it returns :)

comment:8 Changed 3 years ago by jitter

  • Priority changed from undecided to low
  • Status changed from new to closed
  • Resolution set to wontfix

If I read this right this issue is settled. There is no foolproof way to check if a promise() function really returns a promise or something which looks like it.

Feel free to yell at me and to request this ticket to get reopened.

comment:9 in reply to: ↑ 7 Changed 3 years ago by jaubourg

Replying to rmurphey:

Replying to jaubourg:

Testing for then on the returned object doesn't ensure it is a promise either.

 http://jsfiddle.net/9fuHZ/

Design by convention has its limits and no matter how complicated the test becomes, you always have ways around it.

As Dave Methvin pointed out to me in the IRC channel, if we don't know what the promise method on the object passed to $.when does, then we probably don't want to run it to see what it returns :)

What about an object that is observable but doesn't implement the promise interface? Just like a jQuery collection could end up being if something like http://bugs.jquery.com/ticket/7934 was to be implemented (and it makes no sense for a jQuery collection to implement the promise interface since it would only clobber jQuery.fn and be unnecessarily confusing).

Remember that Deferreds implement the promise interface as a convenience and I'm beginning to believe it was a mistake seeing as it turns out to be a bit confusing and hinders the fact that promise() returns an immutable object while deferreds are, obviously, mutable.

At any rate, I don't see this as any different from testing for the presence of a nodeType attribute to determine if an object is a DOM node. Something jQuery does everywhere in the code and that works perfectly as long as the convention is known and no-one attempts to break it.

An earlier version had a specific object attached onto the promise method to "mark" it. But, not only can you work around it, but it would also make using a third-party promise very difficult (ie not a jQuery.Deferred promise, just some other code from another library that implements Promise/A).

As it is today, all it takes to make a third party promise observable is this:

    // Make third-party promise observable
    thirdPartyPromise.promise = function() {
        return this;
    }

    // Or if the implementation is prototype base
    // Add to the prototype so that all promises are now
    // observable by jQuery
    ThirdPartyPromise.prototype.promise = function() {
        return this;
    }

Another advantage is that, if the third-party is not Promise/A compliant, it's pretty easy to return a Promise/A compliant object by doing some more work in the newly created promise method.

This is incidently why jQuery uses a promise method as opposed to a promise property (like dojo and some others do).

Another advantage is that there are far less risks of false positive by using a method rather than a property.

Last edited 3 years ago by jaubourg (previous) (diff)

Please follow the  bug reporting guidlines and use  jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.