mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Deferred: Make jQuery.when synchronous when possible
Closes gh-3102 Fixes gh-3100 Closes gh-3105
This commit is contained in:
parent
e8825a529b
commit
de71e9755f
@ -366,16 +366,21 @@ jQuery.extend( {
|
|||||||
|
|
||||||
// Single- and empty arguments are adopted like Promise.resolve
|
// Single- and empty arguments are adopted like Promise.resolve
|
||||||
if ( remaining <= 1 ) {
|
if ( remaining <= 1 ) {
|
||||||
adoptValue( singleValue, master.resolve, master.reject );
|
adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject );
|
||||||
|
|
||||||
// Use .then() to unwrap secondary thenables (cf. gh-3000)
|
// Use .then() to unwrap secondary thenables (cf. gh-3000)
|
||||||
return master.then();
|
if ( master.state() === "pending" ||
|
||||||
|
jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
|
||||||
|
|
||||||
|
return master.then();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiple arguments are aggregated like Promise.all array elements
|
// Multiple arguments are aggregated like Promise.all array elements
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
|
adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
|
||||||
}
|
}
|
||||||
|
|
||||||
return master.promise();
|
return master.promise();
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
@ -824,24 +824,27 @@ QUnit.test( "jQuery.when(nonThenable) - like Promise.resolve", function( assert
|
|||||||
QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
assert.expect( 56 );
|
var CASES = 16,
|
||||||
|
slice = [].slice,
|
||||||
var slice = [].slice,
|
|
||||||
sentinel = { context: "explicit" },
|
sentinel = { context: "explicit" },
|
||||||
eventuallyFulfilled = jQuery.Deferred().notify( true ),
|
eventuallyFulfilled = jQuery.Deferred().notify( true ),
|
||||||
eventuallyRejected = jQuery.Deferred().notify( true ),
|
eventuallyRejected = jQuery.Deferred().notify( true ),
|
||||||
|
secondaryFulfilled = jQuery.Deferred().resolve( eventuallyFulfilled ),
|
||||||
|
secondaryRejected = jQuery.Deferred().resolve( eventuallyRejected ),
|
||||||
inputs = {
|
inputs = {
|
||||||
promise: Promise.resolve( true ),
|
promise: Promise.resolve( true ),
|
||||||
rejectedPromise: Promise.reject( false ),
|
rejectedPromise: Promise.reject( false ),
|
||||||
deferred: jQuery.Deferred().resolve( true ),
|
deferred: jQuery.Deferred().resolve( true ),
|
||||||
eventuallyFulfilled: eventuallyFulfilled,
|
eventuallyFulfilled: eventuallyFulfilled,
|
||||||
secondaryFulfilled: jQuery.Deferred().resolve( eventuallyFulfilled ),
|
secondaryFulfilled: secondaryFulfilled,
|
||||||
|
eventuallySecondaryFulfilled: jQuery.Deferred().notify( true ),
|
||||||
multiDeferred: jQuery.Deferred().resolve( "foo", "bar" ),
|
multiDeferred: jQuery.Deferred().resolve( "foo", "bar" ),
|
||||||
deferredWith: jQuery.Deferred().resolveWith( sentinel, [ true ] ),
|
deferredWith: jQuery.Deferred().resolveWith( sentinel, [ true ] ),
|
||||||
multiDeferredWith: jQuery.Deferred().resolveWith( sentinel, [ "foo", "bar" ] ),
|
multiDeferredWith: jQuery.Deferred().resolveWith( sentinel, [ "foo", "bar" ] ),
|
||||||
rejectedDeferred: jQuery.Deferred().reject( false ),
|
rejectedDeferred: jQuery.Deferred().reject( false ),
|
||||||
eventuallyRejected: eventuallyRejected,
|
eventuallyRejected: eventuallyRejected,
|
||||||
secondaryRejected: jQuery.Deferred().resolve( eventuallyRejected ),
|
secondaryRejected: secondaryRejected,
|
||||||
|
eventuallySecondaryRejected: jQuery.Deferred().notify( true ),
|
||||||
multiRejectedDeferred: jQuery.Deferred().reject( "baz", "quux" ),
|
multiRejectedDeferred: jQuery.Deferred().reject( "baz", "quux" ),
|
||||||
rejectedDeferredWith: jQuery.Deferred().rejectWith( sentinel, [ false ] ),
|
rejectedDeferredWith: jQuery.Deferred().rejectWith( sentinel, [ false ] ),
|
||||||
multiRejectedDeferredWith: jQuery.Deferred().rejectWith( sentinel, [ "baz", "quux" ] )
|
multiRejectedDeferredWith: jQuery.Deferred().rejectWith( sentinel, [ "baz", "quux" ] )
|
||||||
@ -857,6 +860,7 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
|||||||
deferred: [ true ],
|
deferred: [ true ],
|
||||||
eventuallyFulfilled: [ true ],
|
eventuallyFulfilled: [ true ],
|
||||||
secondaryFulfilled: [ true ],
|
secondaryFulfilled: [ true ],
|
||||||
|
eventuallySecondaryFulfilled: [ true ],
|
||||||
multiDeferred: [ "foo", "bar" ],
|
multiDeferred: [ "foo", "bar" ],
|
||||||
deferredWith: [ true ],
|
deferredWith: [ true ],
|
||||||
multiDeferredWith: [ "foo", "bar" ]
|
multiDeferredWith: [ "foo", "bar" ]
|
||||||
@ -866,6 +870,7 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
|||||||
rejectedDeferred: [ false ],
|
rejectedDeferred: [ false ],
|
||||||
eventuallyRejected: [ false ],
|
eventuallyRejected: [ false ],
|
||||||
secondaryRejected: [ false ],
|
secondaryRejected: [ false ],
|
||||||
|
eventuallySecondaryRejected: [ false ],
|
||||||
multiRejectedDeferred: [ "baz", "quux" ],
|
multiRejectedDeferred: [ "baz", "quux" ],
|
||||||
rejectedDeferredWith: [ false ],
|
rejectedDeferredWith: [ false ],
|
||||||
multiRejectedDeferredWith: [ "baz", "quux" ]
|
multiRejectedDeferredWith: [ "baz", "quux" ]
|
||||||
@ -875,7 +880,9 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
|||||||
// Strict mode functions invoked without .call/.apply get global-object context
|
// Strict mode functions invoked without .call/.apply get global-object context
|
||||||
defaultContext = (function getDefaultContext() { return this; }).call(),
|
defaultContext = (function getDefaultContext() { return this; }).call(),
|
||||||
|
|
||||||
done = assert.async( 28 );
|
done = assert.async( CASES * 2 );
|
||||||
|
|
||||||
|
assert.expect( CASES * 4 );
|
||||||
|
|
||||||
jQuery.each( inputs, function( message, value ) {
|
jQuery.each( inputs, function( message, value ) {
|
||||||
var code = "jQuery.when( " + message + " )",
|
var code = "jQuery.when( " + message + " )",
|
||||||
@ -917,6 +924,8 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
|||||||
setTimeout( function() {
|
setTimeout( function() {
|
||||||
eventuallyFulfilled.resolve( true );
|
eventuallyFulfilled.resolve( true );
|
||||||
eventuallyRejected.reject( false );
|
eventuallyRejected.reject( false );
|
||||||
|
inputs.eventuallySecondaryFulfilled.resolve( secondaryFulfilled );
|
||||||
|
inputs.eventuallySecondaryRejected.resolve( secondaryRejected );
|
||||||
}, 50 );
|
}, 50 );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@ -1049,3 +1058,28 @@ QUnit.test( "jQuery.when - notify does not affect resolved", function( assert )
|
|||||||
assert.ok( false, "Error on resolve" );
|
assert.ok( false, "Error on resolve" );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
QUnit.test( "jQuery.when(...) - opportunistically synchronous", function( assert ) {
|
||||||
|
|
||||||
|
assert.expect( 5 );
|
||||||
|
|
||||||
|
var when = "before",
|
||||||
|
resolved = jQuery.Deferred().resolve( true ),
|
||||||
|
rejected = jQuery.Deferred().reject( false ),
|
||||||
|
validate = function( label ) {
|
||||||
|
return function() {
|
||||||
|
assert.equal( when, "before", label );
|
||||||
|
};
|
||||||
|
},
|
||||||
|
done = assert.async( 5 );
|
||||||
|
|
||||||
|
jQuery.when().done( validate( "jQuery.when()" ) ).always( done );
|
||||||
|
jQuery.when( when ).done( validate( "jQuery.when(nonThenable)" ) ).always( done );
|
||||||
|
jQuery.when( resolved ).done( validate( "jQuery.when(alreadyFulfilled)" ) ).always( done );
|
||||||
|
jQuery.when( rejected ).fail( validate( "jQuery.when(alreadyRejected)" ) ).always( done );
|
||||||
|
jQuery.when( resolved, rejected )
|
||||||
|
.always( validate( "jQuery.when(alreadyFulfilled, alreadyRejected)" ) )
|
||||||
|
.always( done );
|
||||||
|
|
||||||
|
when = "after";
|
||||||
|
} );
|
||||||
|
Loading…
Reference in New Issue
Block a user