Skip to content

Conversation

@gibson042
Copy link
Member

Fixes gh-3029

@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @markelog, @timmywil and @jaubourg to be potential reviewers

@gibson042 gibson042 force-pushed the gh-3029-jQuery-when-deferred branch from c74a03f to 2be1b05 Compare April 26, 2016 21:37
@gibson042 gibson042 changed the title WIP: Split the two sides of jQuery.when Split the two sides of jQuery.when Apr 26, 2016
@gibson042
Copy link
Member Author

   raw     gz Sizes
264540  78519 dist/jquery.js
 86225  30013 dist/jquery.min.js

   raw     gz Compared to master @ f4961822160c671fd72f1da7501049aab6cfd56b
    -5    +51 dist/jquery.js
    +7     -6 dist/jquery.min.js

src/deferred.js Outdated
resolveValues = slice.call( arguments ),
length = resolveValues.length,
when: function( singleValue ) {
var // count of uncompleted subordinates
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment position seems a little off-kilter here. Maybe add a newline or tab? Most likely a newline.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed to match other instances.

@dmethvin
Copy link
Member

Wow, that makes the code a lot easier to understand as well. 👍

src/deferred.js Outdated
var method;

// Check for promise aspect first to privilege synchronous behavior
if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
Copy link
Member

@markelog markelog Apr 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assignment inside of the call is attempt to save some size?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but it's not new. Saves 7 bytes here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the

function adoptValue( value, resolve, reject ) {

    // Check for promise aspect first to privilege synchronous behavior
    if ( value && jQuery.isFunction( value.promise ) ) {
        value.promise.call( value ).done( resolve ).fail( reject );

    // Other thenables
    } else if ( value && jQuery.isFunction( value.then ) ) {
        value.then.call( value, resolve, reject );

    // Other non-thenables
    } else {

        // Support: Android 4.0 only
        // Strict mode functions invoked without .call/.apply get global-object context
        resolve.call( undefined, value );
    }
}

There is not diff in the size?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promises/A+ requires accessing .then only once; if ( jQuery.isFunction( value.then ) ) { value.then.call(…); } is prohibited (cf. Notes 3.5).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't fail any tests in this case then?

Copy link
Member Author

@gibson042 gibson042 Apr 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markelog: Commenting it out won't fail any tests because Promises/A+ only specifies then, and we only define a promises-tests adapter for jQuery.Deferred. I can define a jQuery.when adapter, put in a QUnit test of jQuery.when( pathologicalThenable ), or just let it be, but the line MUST take that form if we guarantee proper treatment of any thenable conformant with Promises/A+ (which, as of 3.0, we do).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And to clarify: if ( jQuery.isFunction( value.then ) ) { value.then.call(…); } is prohibited because it accesses value.then twice, and the results of those accesses won't be identical in the presence of a pathological getter like https://github.com/promises-aplus/promises-tests/blob/0d409df278345753c9527539a5558db67d42bb02/lib/tests/helpers/thenables.js#L29 .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or just let it be, but the line MUST take that form if we guarantee proper

I think such changes should be supported and confirmed by the tests, otherwise all of it could be seen as speculation or subjective interpretation, it seems this discussion revealed luck of it, so i'd say either in this pull or right after this one, we need to add those tests for jQuery.when.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you-da-man

@gibson042 gibson042 force-pushed the gh-3029-jQuery-when-deferred branch from f9fb6be to be8174c Compare April 27, 2016 20:08
@gibson042
Copy link
Member Author

Rebased on the Android 4.0 fix.

   raw     gz Sizes
263375  78345 dist/jquery.js
 86192  29971 dist/jquery.min.js

   raw     gz Compared to master @ 7f1e59343b1600e530472a90aa27a2bcc7b72c96
    -7    +55 dist/jquery.js
    +7     -3 dist/jquery.min.js

@gibson042
Copy link
Member Author

We're now taking a slight hit, but within tolerances. It would be nice to consolidate the when and then helpers in the future.

   raw     gz Sizes
263788  78457 dist/jquery.js
 86222  29977 dist/jquery.min.js

   raw     gz Compared to master @ 7f1e59343b1600e530472a90aa27a2bcc7b72c96
  +406   +167 dist/jquery.js
   +37     +3 dist/jquery.min.js


} );
this.clock.tick( 50 );
this.clock.tick( 100 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funny you should ask... the test uses jQuery.when( elem ).done(…), and this PR updates the single-argument form of jQuery.when to use .then() for unwrapping secondary thenables (e.g., jQuery.when( jQuery.Deferred().resolve( thenable ) )). Single-argument jQuery.when becomes necessarily asynchronous as a side effect, and we therefore require an extra clock tick to invoke the callback.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooo, so we have animate(..., 50), but because when.done is now async we need value more then 50, interesting, you probably were surprised a bit :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single-argument jQuery.when becomes necessarily asynchronous as a side effect

It feels to me like placing a distinction between single argument and multiple argument is a really bad idea. I opened #3100 about this.

@gibson042 gibson042 closed this in 356a3bc May 2, 2016
@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

6 participants