-
Notifications
You must be signed in to change notification settings - Fork 20.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deferred: Backwards-compatible standards interoperability #1996
Conversation
Specific spec and old jQuery compatibility assertions Ref jquery#1821 (comment)
To run tests, invoke `grunt default promises-aplus-tests`. Conflicts: Gruntfile.js package.json src/ajax.js
raw gz Sizes 249270 73674 dist/jquery.js 84800 29540 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +2345 +455 dist/jquery.js +607 +145 dist/jquery.min.js
Non-thenable return from a rejection handler fulfills instead of rejects. Deferreds cannot resolve from progress handlers.
Passes all jQuery QUnit tests. raw gz Sizes 249550 73734 dist/jquery.js 84891 29568 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +2625 +515 dist/jquery.js +698 +173 dist/jquery.min.js raw gz Compared to last run +280 +59 dist/jquery.js +91 +28 dist/jquery.min.js
Reject promise self-resolution loops. raw gz Sizes 249741 73808 dist/jquery.js 84930 29583 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +2816 +589 dist/jquery.js +737 +188 dist/jquery.min.js raw gz Compared to last run +191 +74 dist/jquery.js +39 +15 dist/jquery.min.js
Retrieve `then` only once per fulfillment value. raw gz Sizes 249976 73882 dist/jquery.js 84938 29589 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +3051 +663 dist/jquery.js +745 +194 dist/jquery.min.js raw gz Compared to last run +235 +74 dist/jquery.js +8 +6 dist/jquery.min.js
Skip setTimeout for re-resolution so synchronous errors don't interrupt it. raw gz Sizes 250371 73993 dist/jquery.js 84968 29606 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +3446 +774 dist/jquery.js +775 +211 dist/jquery.min.js raw gz Compared to last run +395 +111 dist/jquery.js +30 +17 dist/jquery.min.js
Ignore double-resolution attempts. raw gz Sizes 250582 74046 dist/jquery.js 84978 29614 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +3657 +827 dist/jquery.js +785 +219 dist/jquery.min.js raw gz Compared to last run +211 +53 dist/jquery.js +10 +8 dist/jquery.min.js
Ignore post-resolution exceptions. raw gz Sizes 250862 74103 dist/jquery.js 84992 29621 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +3937 +884 dist/jquery.js +799 +226 dist/jquery.min.js raw gz Compared to last run +280 +57 dist/jquery.js +14 +7 dist/jquery.min.js
Only check objects and functions for thenability. raw gz Sizes 251129 74152 dist/jquery.js 85036 29630 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +4204 +933 dist/jquery.js +843 +235 dist/jquery.min.js raw gz Compared to last run +267 +49 dist/jquery.js +44 +9 dist/jquery.min.js
}), | ||
done = jQuery.map( new Array( 3 ), function() { return assert.async(); } ); | ||
|
||
piped.fail(function( result ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That piped deferreds inherit rejection is the reason why I couldn't justify dropping .pipe
... the standard and our current behavior are just too divergent here.
Wow. I'll be reading through this today ... maybe tomorrow as well. :) |
// Support: Promises/A+ section 2.3.3.3.4.1 | ||
// https://promisesaplus.com/#point-61 | ||
// Ignore post-resolution exceptions | ||
if ( depth + 1 >= maxDepth ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the part in the story where it swallows errors. Some of the libs do complicated "next-turn" checking but I wonder if we could just do a console.log
if the error that was thrown is one of the developer-screwup errors like SyntaxError
. Something as simple as this?
if ( /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error/.test(e) ) {
console.log("[Caught exception] "+e);
console.trace();
}
It could be in a public method that users could override perhaps?
Also note we only have one test case for throw
n exceptions and none for browser-initiated exceptions.
This is really awesome. 👏 I want to understand it a little more, the spec references are helping. |
👏 indeed /cc @domenic |
It looks like the |
That's definitely in scope here. I'll update it. |
Unwrap thenables for progress handlers Await fulfillment (ONLY) from thenables returned by progress handlers * Ignore progress * Throw rejections raw gz Sizes 252116 74390 dist/jquery.js 85040 29641 dist/jquery.min.js raw gz Compared to master @ 66e1b6b +5191 +1171 dist/jquery.js +847 +246 dist/jquery.min.js raw gz Compared to last run +987 +239 dist/jquery.js +4 +11 dist/jquery.min.js
After some thought, I ended up nearly reversing the last block above... thenables returned from Still to do:
|
I would be fine with corralling |
So that would involve It's also a bigger backcompat break, but I don't know if that's a good thing or a bad thing here. I'd like to further point out that these cases are just as potentially problematic with |
This may be more of a use case for jQuery.Migrate, but what about adding warnings in the unminified versions to warn the user if I'm just thinking about the nasty case of |
@jaubourg and @jquery/core: |
In order to deal with multiple arguments in |
Just another point of concern with synchronous ajax calls: I just took a look and unless I missed them, there are no unit tests that assert the ordering of callbacks. Since all handlers ( including the inline success, error, and complete options ) are attached using Deferreds, this change might have the effect of "breaking" synchronous ajax in that the callbacks will no longer be called synchronously. |
@dcherman using deferreds with synchronous AJAX calls is not and has not been supported as of 1.8. Quoting the manual:
|
@benjamingr I did forget about that, but my point still stands actually unless I'm misunderstanding something: https://github.com/jquery/jquery/blob/master/src/ajax.js#L490-L492 The callback options just add the callbacks to the Deferred which is now resolved asynchronously, no? |
@dcherman: this change forces In short: only Do you foresee that causing problems? If so, I'm not sure anything can be done, since the asynchronicity is explicitly specified. |
@gibson042 Ah I see how it works now, I misunderstood how this change worked. Since as @benjamingr pointed it the Deferred/Promise methods have been deprecated for sync XHR since 1.8, it shouldn't officially cause a problem. I'm sure there are people out there that were depending on |
@gibson042 How bout we land this? |
I didn't get a chance to merge this, but did clean up some text. At this point, I feel like it's good to go and the remaining work can be dealt with later. |
Awesome! Great news On Wed, Feb 25, 2015 at 7:25 PM, Richard Gibson notifications@github.com
|
Hey @gibson042, reminder to merge this when you get a chance. Thanks! |
Fixes gh-8044 Closes gh-8047 Ref jquery/jquery#1996
Ref #1821 (comment)
Maintained backwards compatibility (outside of specifications):
dfd.resolve( thenable ).done( expectsThenable )
dfd.resolve( value1, value2, ... ).then( expectsMultipleArguments )
dfd.notify( progress ).then( null, null, expectsInvocation )
dfd.resolveWith( context, values ).then( expectsContext )
Necessarily-breaking changes
return
value (i.e., not thrown) from onRejected handlers can fulfill a.then
Deferred:dfd.reject().then( null, jQuery.noop ).done( expectsInvocation )
Potentially-breaking behavior decisions (current state of this PR in bold):
.then
onProgress handlers.pipe
behavior: preserve as-is vs. support non-promiseable thenables.pipe
support: deprecate vs. keep vs. drop.pipe
/.then
incompatibilities: prefix tests with[DIVERGENT]
vs. ???jQuery.when
: privilege.promise
(e.g., provide context) vs. privilege.then
To Do:
jQuery.when
unhandledRejections
plugin