Propagate context of returned deferred object in Deferred.then(). Fixes #13160.

This commit is contained in:
nanto 2013-01-08 16:27:13 +01:00 committed by Dave Methvin
parent 4694118ef7
commit 0c5d2fbabb
2 changed files with 30 additions and 17 deletions

View File

@ -21,22 +21,19 @@ jQuery.extend({
return jQuery.Deferred(function( newDefer ) { return jQuery.Deferred(function( newDefer ) {
jQuery.each( tuples, function( i, tuple ) { jQuery.each( tuples, function( i, tuple ) {
var action = tuple[ 0 ], var action = tuple[ 0 ],
fn = fns[ i ]; fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
// deferred[ done | fail | progress ] for forwarding actions to newDefer // deferred[ done | fail | progress ] for forwarding actions to newDefer
deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? deferred[ tuple[1] ](function() {
function() { var returned = fn && fn.apply( this, arguments );
var returned = fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) {
if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise()
returned.promise() .done( newDefer.resolve )
.done( newDefer.resolve ) .fail( newDefer.reject )
.fail( newDefer.reject ) .progress( newDefer.notify );
.progress( newDefer.notify ); } else {
} else { newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, [ returned ] ); }
} });
} :
newDefer[ action ]
);
}); });
fns = null; fns = null;
}).promise(); }).promise();
@ -72,7 +69,7 @@ jQuery.extend({
// deferred[ resolve | reject | notify ] // deferred[ resolve | reject | notify ]
deferred[ tuple[0] ] = function() { deferred[ tuple[0] ] = function() {
deferred[ tuple[0] + "With" ]( promise, arguments ); deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
return this; return this;
}; };
deferred[ tuple[0] + "With" ] = list.fireWith; deferred[ tuple[0] + "With" ] = list.fireWith;

View File

@ -273,7 +273,7 @@ test( "jQuery.Deferred.then - deferred (progress)", function() {
test( "jQuery.Deferred.then - context", function() { test( "jQuery.Deferred.then - context", function() {
expect( 4 ); expect( 7 );
var context = {}; var context = {};
@ -284,6 +284,12 @@ test( "jQuery.Deferred.then - context", function() {
strictEqual( value, 6, "proper value received" ); strictEqual( value, 6, "proper value received" );
}); });
jQuery.Deferred().resolve().then(function() {
return jQuery.Deferred().resolveWith(context);
}).done(function() {
strictEqual( this, context, "custom context of returned deferred correctly propagated" );
});
var defer = jQuery.Deferred(), var defer = jQuery.Deferred(),
piped = defer.then(function( value ) { piped = defer.then(function( value ) {
return value * 3; return value * 3;
@ -295,6 +301,16 @@ test( "jQuery.Deferred.then - context", function() {
strictEqual( this, piped, "default context gets updated to latest promise in the chain" ); strictEqual( this, piped, "default context gets updated to latest promise in the chain" );
strictEqual( value, 6, "proper value received" ); strictEqual( value, 6, "proper value received" );
}); });
var defer2 = jQuery.Deferred(),
piped2 = defer2.then();
defer2.resolve( 2 );
piped2.done(function( value ) {
strictEqual( this, piped2, "default context gets updated to latest promise in the chain (without passing function)" );
strictEqual( value, 2, "proper value received (without passing function)" );
});
}); });
test( "jQuery.when", function() { test( "jQuery.when", function() {