Skip to main content

Bug Tracker

Side navigation

#14510 closed bug (migrated)

Opened November 04, 2013 02:32PM UTC

Closed October 20, 2014 10:25PM UTC

Improve API interoperability with standard Promise

Reported by: jzaefferer Owned by:
Priority: high Milestone: 1.12/2.2
Component: deferred Version: 1.10.2
Keywords: Cc:
Blocked by: Blocking:
Description

Discussed this at the jQuery team meeting in Amsterdam: The spec is still changing a lot (within whatwg and draft pages on github), so we'll wait for it to ship, unprefixed, not behind a flag, in stable browsers first.

Once that happened, we should change/fix our implementation to match the spec (and shipped implementation).

Can use .pipe() to continue using any jQuery-specific functionality.

Attachments (0)
Change History (19)

Changed November 04, 2013 02:58PM UTC by timmywil comment:1

component: unfileddeferred
priority: undecidedhigh
status: newopen

Changed December 18, 2013 02:52PM UTC by dj.gilcrease@kanbansolutions.com comment:2

Make jQuery.Defered / promise closer to conforming to the specification around exceptions. I have not checked the full compliance tests from https://github.com/promises-aplus/promises-tests but I have setup a test that shows the exception handling working as expected http://jsfiddle.net/yEXL4/1/

Pull Request @ https://github.com/jquery/jquery/pull/1462

Changed December 18, 2013 03:07PM UTC by dmethvin comment:3

I don't think this is the right way to go. You're swallowing an exception silently and it will only be reported (poorly) if the user has the foresight to attach a fail handler. See #11193, #11292.

Even in the current proposed spec discussions there's some handwaving about needing browser support in dev tools to be able to debug properly.

What I'd prefer to do is have it so that users can opt into standard ES6 Promises or a compliant polyfill. Retroactively changing the semantics of Deferred in a significant way seems like a bad idea, especially with no built-in support to notify about unhandled promise rejections.

Changed December 19, 2013 12:10PM UTC by markelog comment:4

This ticket requires clarification.

Specification that mentioned in ticket description is this one which refers to Domenic repository.

There is also promises/A and promises/A+ "proposals". Which are not much of a relevance right now.

Plus upcoming draft of ES6 which should also have Promise clause.

DOM specification is in the draft stage, but it's already implemented in two browsers – Firefox (Nightly) and Chrome (Canary) without any prefixes, both browsers however has some implementation mistakes.

New specification defines new API which significantly differs from the jQuery Deferred, aside from methods like "cast", "catch", etc; it also has these behaivor differences:

1. Guarantee asynchronous execution

2. Swallows errors then passes and propagate them to the stack of rejection handlers

3. Does not have progress handler in "then" signature

4. Always passes only one argument to successful/failed callbacks

Changed December 19, 2013 03:51PM UTC by dmethvin comment:5

It's definitely good to emphasize that Promises/A+ is just a proposal and not a standard to comply with. jQuery has had Deferred for several years now and I would guess it has the most number of users of any Promise/Deferred implementation that exists today. Let's not break that code, keep Deferred the way it is, and look for ways to let developers use the emerging standard.

There has been some lively discussion around the addition of a .done() method to ES6 Promises that would not swallow exceptions, but it doesn't seem to be slated for the first iteration of the standard. I think that's a shame, because .then() can be built from .done() but not the other way around. Without the proposed browser support for exposing unhandled exceptions, Promises are going to be very difficult to debug.

Changed December 19, 2013 04:34PM UTC by rwaldron comment:6

Replying to [comment:4 markelog]:

This ticket requires clarification. Specification that mentioned in ticket description is this one which refers to Domenic repository.

This is the Promises specification that will be in ES6

Changed December 20, 2013 09:57PM UTC by domenic@domenicdenicola.com comment:7

Promises/A+ is a standard and is the basis for the ES6 promises specification. All promises that follow the ES6 promise specification will pass all Promises/A+ tests. The ES6 promises spec is in effect a superset of the Promises/A+ spec.

Changed December 20, 2013 09:59PM UTC by anonymous comment:8

.then() can be built from .done() but not the other way around.

This is false.

Promise.prototype.done = (onFulfilled, onRejected) {
  this.then(onFulfilled, onRejected).catch(e => setTimeout(() => throw e, 0));
};

Changed December 20, 2013 10:10PM UTC by dmethvin comment:9

_comment0: Re-throwing an error object that has propagated to you isn't the same as letting the browser handle the error at the point where it occurred. A lot of important error context is lost, especially on older browsers (which 1.x still supports). \ \ However, this particular ticket is about trying to turn Deferred into Promises/A+. We can't do that, it would break a few years worth of existing code that is already using Deferred. Nobody wants to break the web. Instead we expect to support ES6 Promises like I mentioned above. That seems like a good approach?1387577921832559

Re-throwing an error object that has propagated to you isn't the same as letting the browser handle the error at the point where it occurred. A lot of important error context is lost, especially on older browsers (which 1.x still supports).

However, that particular pull request listed above is about trying to turn Deferred into Promises/A+. We can't do that, it would break a few years worth of existing code that is already using Deferred. Nobody wants to break the web. Instead we expect to support ES6 Promises like I mentioned above. That seems like a good approach?

EDIT: Clarified the subject; the reason this ticket isn't closed is because we expect to support ES6 Promises but are not changing Deferred.

Changed December 20, 2013 10:58PM UTC by domenic@domenicdenicola.com comment:10

I guess it's unclear what the OP meant by

Make promises spec-compliant
... we should change/fix our implementation to match the spec (and shipped implementation).
Can use .pipe() to continue using any jQuery-specific functionality.

It sounds like you are saying something different from the OP, wherein you do not change/fix your implementation to match the spec, but instead somehow support real promises (unclear how).

Changed December 20, 2013 11:07PM UTC by dmethvin comment:11

Reading through this, I agree it's unclear. The pull request referencing this issue was misplaced, since the OP doesn't mention changing our Deferred at all. If it becomes too confusing we can close this and open a new ticket with a more specific title.

Changed December 20, 2013 11:18PM UTC by m_gol comment:12

I was at the Amsterdam meeting where it was discussed. OP says about compliance with ES6 spec. If wording is not clear, we can modify title & text of the issue but I'd prefer not to re-create one since discussion already started here.

Changed December 20, 2013 11:33PM UTC by m_gol comment:13

We can discuss it in San Diego but, surprisingly, jaubourg seemed ok to switch once at least 2 stable browsers implement the new spec while keeping pipe with current semantics.

I'd like to see how much code would be affected, I don't think many people relied (in the production code) on the promise throwing errors as a way of flow control. OTH, for jQuery even a small amount can be a lot.

There's a larger question of how we deprecate old APIs, e.g. in case of $.ajax and the planned $.xhr. Will we ever be able to actually remove the former? The question here is of similar concern.

Changed January 13, 2014 10:52PM UTC by calvin.metcalf@gmail.com comment:14

Chrome beta implements them and Firefox beta has them out from under a flag, so 2 stable browsers will be soon.

Changed January 14, 2014 11:07AM UTC by markelog comment:15

Replying to [comment:14 calvin.metcalf@…]:

Chrome beta implements them and Firefox beta has them out from under a flag, so 2 stable browsers will be soon.

See ticket description – "so we'll wait for it to ship, unprefixed, not behind a flag, in stable browsers first"

Changed February 05, 2014 12:02PM UTC by anonymous comment:16

Unwrapping thenables is also a change you should consider doing. It's in the spec and it's useful.

Changed March 17, 2014 05:45PM UTC by dmethvin comment:17

summary: Make promises spec-compliantImprove API interoperability with standard Promise

I've edited the title to be more in line with what we actually plan to do for 1.12/2.2. We are not converting our internal uses of $.Deferred to the emerging Promise implementations, the semantics of the two differ too much and Promise lacks several features that $.Deferred uses, such as progress callbacks and multiple arguments.

However, we do plan on accepting Promise as an input where appropriate (e.g., $.when). and ensuring that $.Deferred works as a thenable.

Changed March 21, 2014 04:16PM UTC by dmethvin comment:18

milestone: None1.12/2.2

Changed October 20, 2014 10:25PM UTC by m_gol comment:19

resolution: → migrated
status: openclosed