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

$.when should always be synchronous when possible #3100

Closed
marcandre opened this Issue May 3, 2016 · 5 comments

Comments

Projects
None yet
4 participants
@marcandre

IIC, jQuery 3.0 will have then be A+ compatible in that callbacks are always executed out of context (e.g with setTimeout), while done will continue to be executed synchronously whenever possible (eager).

I was double checking that $.when kept the eager behavior and discovered that it does, unless there's a single argument:

p = $.Deferred()
p.resolveWith(42);
p.done(function() {console.log('A')});
$.when(p).done(function() {console.log('B')});
$.when(p, p).done(function() {console.log('C')});
console.log('D');

I was hope to get ABCD, given that the promised is already resolved when the done are called, and dreaded ADBC if $when was no longer eager. I get worse though. Console is ACDB, which is not acceptable; $.when(p) and $.when(p, p) should behave the exact same way.

FWIW, I personally disagree with Promise/A+'s rule 2.2.4 and I hope jQuery keeps all behavior eager (except for then to comply with A+) and gives us an eager version of then (could be pipe, but with the correct semantics for callbacks return values).

I did not investigate any further, but it looks related to #3059.

@markelog

This comment has been minimized.

Show comment
Hide comment
@markelog

markelog May 3, 2016

Member

@gibson042 Did we discuss this before? Did we want to make done async or sync? I agree arguments shouldn't affect on it

Member

markelog commented May 3, 2016

@gibson042 Did we discuss this before? Did we want to make done async or sync? I agree arguments shouldn't affect on it

@markelog markelog added the Deferred label May 3, 2016

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 May 3, 2016

Member

It's important to realize that jQuery.when is polymorphic—multi-argument calls being analogous to ES6 Promise.all and other calls being analogous to ES6 Promise.resolve. It's unfortunate that their similarity led to a shared function name in jQuery, but they are distinct. And although done itself remains eager, general-case jQuery.when( value ) is necessarily not because of its reliance on .then to unwrap secondary thenables as Promise.resolve does. And I don't want to introduce a jQuery.when( nonThenable ) exception, which really would introduce an inconsistency.

I also disagree with Promises/A+ 2.2.4, but that is insufficient justification to abandon compatibility which has been demanded for so long.

Member

gibson042 commented May 3, 2016

It's important to realize that jQuery.when is polymorphic—multi-argument calls being analogous to ES6 Promise.all and other calls being analogous to ES6 Promise.resolve. It's unfortunate that their similarity led to a shared function name in jQuery, but they are distinct. And although done itself remains eager, general-case jQuery.when( value ) is necessarily not because of its reliance on .then to unwrap secondary thenables as Promise.resolve does. And I don't want to introduce a jQuery.when( nonThenable ) exception, which really would introduce an inconsistency.

I also disagree with Promises/A+ 2.2.4, but that is insufficient justification to abandon compatibility which has been demanded for so long.

@gibson042 gibson042 closed this May 3, 2016

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin May 3, 2016

Member

I know @gibson042 has rightly railed about this several times, I'm too lazy to dig it up.

In the pre-3.0 implementation there was a special case of "If there is only one argument, and it is a Deferred rather than a plain value, return that argument." In 3.0 we are accepting any type of thenables as arguments, so it would make the $.when behavior even more bizarre because if you passed in a thenable we'd need to convert it to a Deferred to meet the API contract, right? That means there always has to be a hidden async theninside $.when for this to not be a tear-your-hair-out behavior.

Edit: What @gibson042 said.

Member

dmethvin commented May 3, 2016

I know @gibson042 has rightly railed about this several times, I'm too lazy to dig it up.

In the pre-3.0 implementation there was a special case of "If there is only one argument, and it is a Deferred rather than a plain value, return that argument." In 3.0 we are accepting any type of thenables as arguments, so it would make the $.when behavior even more bizarre because if you passed in a thenable we'd need to convert it to a Deferred to meet the API contract, right? That means there always has to be a hidden async theninside $.when for this to not be a tear-your-hair-out behavior.

Edit: What @gibson042 said.

@markelog

This comment has been minimized.

Show comment
Hide comment
@markelog

markelog May 3, 2016

Member

So, jQuery.when is always async right?

Member

markelog commented May 3, 2016

So, jQuery.when is always async right?

@markelog

This comment has been minimized.

Show comment
Hide comment
@markelog

markelog May 3, 2016

Member

So, jQuery.when is always async right?

I answer myself here - no it is not.

Discuss this with @gibson042 on irc, it seems there is motivation to make this call always async regardless of the arguments, opened a different issue for that - #3102

Member

markelog commented May 3, 2016

So, jQuery.when is always async right?

I answer myself here - no it is not.

Discuss this with @gibson042 on irc, it seems there is motivation to make this call always async regardless of the arguments, opened a different issue for that - #3102

@markelog markelog assigned markelog and unassigned markelog May 3, 2016

gibson042 added a commit to gibson042/jquery that referenced this issue May 5, 2016

gibson042 added a commit to gibson042/jquery that referenced this issue May 5, 2016

gibson042 added a commit to gibson042/jquery that referenced this issue May 9, 2016

@gibson042 gibson042 added this to the 3.0.0 milestone May 9, 2016

@lock lock bot locked as resolved and limited conversation to collaborators Jun 18, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.