Implements joined jQuery.when statements. Makes it so calling jQuery.when with no parameter returns a resolved promise. Ensures promise method on promises supports the promise(obj) signature. Ensures a deferred and its promise always return the same promise (itself for the promise). Unit tests provided.
This commit is contained in:
parent
cfca6d3836
commit
c272f5f7da
2 changed files with 79 additions and 14 deletions
45
src/core.js
45
src/core.js
|
@ -898,9 +898,10 @@ jQuery.extend({
|
|||
Deferred: function( func ) {
|
||||
|
||||
var deferred = jQuery._Deferred(),
|
||||
failDeferred = jQuery._Deferred();
|
||||
failDeferred = jQuery._Deferred(),
|
||||
promise;
|
||||
|
||||
// Add errorDeferred methods and redefine cancel
|
||||
// Add errorDeferred methods, then and promise
|
||||
jQuery.extend( deferred , {
|
||||
|
||||
then: function( doneCallbacks , failCallbacks ) {
|
||||
|
@ -914,13 +915,15 @@ jQuery.extend({
|
|||
// Get a promise for this deferred
|
||||
// If obj is provided, the promise aspect is added to the object
|
||||
promise: function( obj ) {
|
||||
obj = obj || {};
|
||||
jQuery.each( "then done fail isResolved isRejected".split( " " ) , function( _ , method ) {
|
||||
if ( obj == null ) {
|
||||
if ( promise ) {
|
||||
return promise;
|
||||
}
|
||||
promise = obj = {};
|
||||
}
|
||||
jQuery.each( "then done fail isResolved isRejected promise".split( " " ) , function( _ , method ) {
|
||||
obj[ method ] = deferred[ method ];
|
||||
});
|
||||
obj.promise = function() {
|
||||
return obj;
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -942,10 +945,32 @@ jQuery.extend({
|
|||
|
||||
// Deferred helper
|
||||
when: function( object ) {
|
||||
object = object && jQuery.isFunction( object.promise ) ?
|
||||
var args = arguments,
|
||||
length = args.length,
|
||||
deferred = length <= 1 && object && jQuery.isFunction( object.promise ) ?
|
||||
object :
|
||||
jQuery.Deferred().resolve( object );
|
||||
return object.promise();
|
||||
jQuery.Deferred(),
|
||||
promise = deferred.promise(),
|
||||
resolveArray;
|
||||
|
||||
if ( length > 1 ) {
|
||||
resolveArray = new Array( length );
|
||||
jQuery.each( args, function( index, element, args ) {
|
||||
jQuery.when( element ).done( function( value ) {
|
||||
args = arguments;
|
||||
resolveArray[ index ] = args.length > 1 ? slice.call( args , 0 ) : value;
|
||||
if( ! --length ) {
|
||||
deferred.fire( promise, resolveArray );
|
||||
}
|
||||
}).fail( function() {
|
||||
deferred.fireReject( promise, arguments );
|
||||
});
|
||||
return !deferred.isRejected();
|
||||
});
|
||||
} else if ( deferred !== object ) {
|
||||
deferred.resolve( object );
|
||||
}
|
||||
return promise;
|
||||
},
|
||||
|
||||
// Use of jQuery.browser is frowned upon.
|
||||
|
|
|
@ -21,7 +21,7 @@ test("jQuery()", function() {
|
|||
equals( jQuery(null).length, 0, "jQuery(null) === jQuery([])" );
|
||||
equals( jQuery("").length, 0, "jQuery('') === jQuery([])" );
|
||||
|
||||
var obj = jQuery("div")
|
||||
var obj = jQuery("div");
|
||||
equals( jQuery(obj).selector, "div", "jQuery(jQueryObj) == jQueryObj" );
|
||||
|
||||
// can actually yield more than one, when iframes are included, the window is an array as well
|
||||
|
@ -1003,7 +1003,7 @@ test("jQuery._Deferred()", function() {
|
|||
|
||||
test("jQuery.Deferred()", function() {
|
||||
|
||||
expect( 4 );
|
||||
expect( 6 );
|
||||
|
||||
jQuery.Deferred( function( defer ) {
|
||||
strictEqual( this , defer , "Defer passed as this & first argument" );
|
||||
|
@ -1023,11 +1023,16 @@ test("jQuery.Deferred()", function() {
|
|||
}, function() {
|
||||
ok( true , "Error on reject" );
|
||||
});
|
||||
|
||||
var tmp = jQuery.Deferred();
|
||||
|
||||
strictEqual( tmp.promise() , tmp.promise() , "Test deferred always return same promise" );
|
||||
strictEqual( tmp.promise() , tmp.promise().promise() , "Test deferred's promise always return same promise as deferred" );
|
||||
});
|
||||
|
||||
test("jQuery.when()", function() {
|
||||
|
||||
expect( 21 );
|
||||
expect( 23 );
|
||||
|
||||
// Some other objects
|
||||
jQuery.each( {
|
||||
|
@ -1050,6 +1055,10 @@ test("jQuery.when()", function() {
|
|||
|
||||
} );
|
||||
|
||||
ok( jQuery.isFunction( jQuery.when().then( function( resolveValue ) {
|
||||
strictEqual( resolveValue , undefined , "Test the promise was resolved with no parameter" );
|
||||
} ).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" );
|
||||
|
||||
var cache, i;
|
||||
|
||||
for( i = 1 ; i < 4 ; i++ ) {
|
||||
|
@ -1064,6 +1073,37 @@ test("jQuery.when()", function() {
|
|||
}
|
||||
});
|
||||
|
||||
test("jQuery.when() - joined", function() {
|
||||
|
||||
expect(8);
|
||||
|
||||
jQuery.when( 1, 2, 3 ).done( function( a, b, c ) {
|
||||
strictEqual( a , 1 , "Test first param is first resolved value - non-observables" );
|
||||
strictEqual( b , 2 , "Test second param is second resolved value - non-observables" );
|
||||
strictEqual( c , 3 , "Test third param is third resolved value - non-observables" );
|
||||
}).fail( function() {
|
||||
ok( false , "Test the created deferred was resolved - non-observables");
|
||||
});
|
||||
|
||||
var successDeferred = jQuery.Deferred().resolve( 1 , 2 , 3 ),
|
||||
errorDeferred = jQuery.Deferred().reject( "error" , "errorParam" );
|
||||
|
||||
jQuery.when( 1 , successDeferred , 3 ).done( function( a, b, c ) {
|
||||
strictEqual( a , 1 , "Test first param is first resolved value - resolved observable" );
|
||||
same( b , [ 1 , 2 , 3 ] , "Test second param is second resolved value - resolved observable" );
|
||||
strictEqual( c , 3 , "Test third param is third resolved value - resolved observable" );
|
||||
}).fail( function() {
|
||||
ok( false , "Test the created deferred was resolved - resolved observable");
|
||||
});
|
||||
|
||||
jQuery.when( 1 , errorDeferred , 3 ).done( function() {
|
||||
ok( false , "Test the created deferred was rejected - rejected observable");
|
||||
}).fail( function( error , errorParam ) {
|
||||
strictEqual( error , "error" , "Test first param is first rejected value - rejected observable" );
|
||||
strictEqual( errorParam , "errorParam" , "Test second param is second rejected value - rejected observable" );
|
||||
});
|
||||
});
|
||||
|
||||
test("jQuery.subclass", function(){
|
||||
expect(378);
|
||||
|
||||
|
|
Loading…
Reference in a new issue