Skip to content

Commit af85a48

Browse files
committed
Deferred: Remove default callback context
Fixes gh-3060
1 parent e5ffcb0 commit af85a48

File tree

2 files changed

+45
-32
lines changed

2 files changed

+45
-32
lines changed

src/deferred.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jQuery.extend( {
6060
.fail( newDefer.reject );
6161
} else {
6262
newDefer[ tuple[ 0 ] + "With" ](
63-
this === promise ? newDefer.promise() : this,
63+
this,
6464
fn ? [ returned ] : arguments
6565
);
6666
}
@@ -73,7 +73,7 @@ jQuery.extend( {
7373
var maxDepth = 0;
7474
function resolve( depth, deferred, handler, special ) {
7575
return function() {
76-
var that = this === promise ? undefined : this,
76+
var that = this,
7777
args = arguments,
7878
mightThrow = function() {
7979
var returned, then;
@@ -144,8 +144,7 @@ jQuery.extend( {
144144

145145
// Process the value(s)
146146
// Default process is resolve
147-
( special || deferred.resolveWith )(
148-
that || deferred.promise(), args );
147+
( special || deferred.resolveWith )( that, args );
149148
}
150149
},
151150

@@ -174,8 +173,7 @@ jQuery.extend( {
174173
args = [ e ];
175174
}
176175

177-
deferred.rejectWith( that || deferred.promise(),
178-
args );
176+
deferred.rejectWith( that, args );
179177
}
180178
}
181179
};
@@ -282,7 +280,7 @@ jQuery.extend( {
282280
// deferred.resolve = function() { deferred.resolveWith(...) }
283281
// deferred.reject = function() { deferred.rejectWith(...) }
284282
deferred[ tuple[ 0 ] ] = function() {
285-
deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
283+
deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
286284
return this;
287285
};
288286

test/unit/deferred.js

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,21 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
1616

1717
assert.ok( jQuery.isFunction( defer.pipe ), "defer.pipe is a function" );
1818

19-
createDeferred().resolve().done( function() {
19+
defer.resolve().done( function() {
2020
assert.ok( true, "Success on resolve" );
21-
assert.strictEqual( this.state(), "resolved", "Deferred is resolved (state)" );
21+
assert.strictEqual( defer.state(), "resolved", "Deferred is resolved (state)" );
2222
} ).fail( function() {
2323
assert.ok( false, "Error on resolve" );
2424
} ).always( function() {
2525
assert.ok( true, "Always callback on resolve" );
2626
} );
2727

28-
createDeferred().reject().done( function() {
28+
defer = createDeferred();
29+
defer.reject().done( function() {
2930
assert.ok( false, "Success on reject" );
3031
} ).fail( function() {
3132
assert.ok( true, "Error on reject" );
32-
assert.strictEqual( this.state(), "rejected", "Deferred is rejected (state)" );
33+
assert.strictEqual( defer.state(), "rejected", "Deferred is rejected (state)" );
3334
} ).always( function() {
3435
assert.ok( true, "Always callback on reject" );
3536
} );
@@ -405,21 +406,31 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - deferred (progress)", function(
405406

406407
QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
407408

408-
assert.expect( 7 );
409+
assert.expect( 11 );
409410

410411
var defer, piped, defer2, piped2,
411-
context = {},
412-
done = jQuery.map( new Array( 4 ), function() { return assert.async(); } );
412+
context = { custom: true },
413+
done = jQuery.map( new Array( 5 ), function() { return assert.async(); } );
413414

414415
jQuery.Deferred().resolveWith( context, [ 2 ] ).then( function( value ) {
416+
assert.strictEqual( this, context, "custom context received by .then handler" );
415417
return value * 3;
416418
} ).done( function( value ) {
417-
assert.notStrictEqual( this, context, "custom context not propagated through .then" );
419+
assert.notStrictEqual( this, context,
420+
"custom context not propagated through .then handler" );
418421
assert.strictEqual( value, 6, "proper value received" );
419422
done.pop().call();
420423
} );
421424

425+
jQuery.Deferred().resolveWith( context, [ 2 ] ).then().done( function( value ) {
426+
assert.strictEqual( this, context,
427+
"custom context propagated through .then without handler" );
428+
assert.strictEqual( value, 2, "proper value received" );
429+
done.pop().call();
430+
} );
431+
422432
jQuery.Deferred().resolve().then( function() {
433+
assert.strictEqual( this, window, "default context in .then handler" );
423434
return jQuery.Deferred().resolveWith( context );
424435
} ).done( function() {
425436
assert.strictEqual( this, context,
@@ -435,8 +446,7 @@ QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
435446
defer.resolve( 2 );
436447

437448
piped.done( function( value ) {
438-
assert.strictEqual( this, piped,
439-
"default context gets updated to latest promise in the chain" );
449+
assert.strictEqual( this, window, ".then handler does not introduce context" );
440450
assert.strictEqual( value, 6, "proper value received" );
441451
done.pop().call();
442452
} );
@@ -447,30 +457,39 @@ QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
447457
defer2.resolve( 2 );
448458

449459
piped2.done( function( value ) {
450-
assert.strictEqual( this, piped2,
451-
"default context updated to latest promise in the chain (without passing function)" );
460+
assert.strictEqual( this, window, ".then without handler does not introduce context" );
452461
assert.strictEqual( value, 2, "proper value received (without passing function)" );
453462
done.pop().call();
454463
} );
455464
} );
456465

457466
QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
458467

459-
assert.expect( 7 );
468+
assert.expect( 11 );
460469

461470
var defer, piped, defer2, piped2,
462-
context = {},
463-
done = jQuery.map( new Array( 4 ), function() { return assert.async(); } );
471+
context = { custom: true },
472+
done = jQuery.map( new Array( 5 ), function() { return assert.async(); } );
464473

465474
jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe( function( value ) {
475+
assert.strictEqual( this, context, "custom context received by .pipe handler" );
466476
return value * 3;
467477
} ).done( function( value ) {
468-
assert.strictEqual( this, context, "[PIPE ONLY] custom context correctly propagated" );
478+
assert.strictEqual( this, context,
479+
"[PIPE ONLY] custom context propagated through .pipe handler" );
469480
assert.strictEqual( value, 6, "proper value received" );
470481
done.pop().call();
471482
} );
472483

484+
jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe().done( function( value ) {
485+
assert.strictEqual( this, context,
486+
"[PIPE ONLY] custom context propagated through .pipe without handler" );
487+
assert.strictEqual( value, 2, "proper value received" );
488+
done.pop().call();
489+
} );
490+
473491
jQuery.Deferred().resolve().pipe( function() {
492+
assert.strictEqual( this, window, "default context in .pipe handler" );
474493
return jQuery.Deferred().resolveWith( context );
475494
} ).done( function() {
476495
assert.strictEqual( this, context,
@@ -486,8 +505,7 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
486505
defer.resolve( 2 );
487506

488507
piped.done( function( value ) {
489-
assert.strictEqual( this, piped,
490-
"default context gets updated to latest promise in the chain" );
508+
assert.strictEqual( this, window, ".pipe handler does not introduce context" );
491509
assert.strictEqual( value, 6, "proper value received" );
492510
done.pop().call();
493511
} );
@@ -498,8 +516,7 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
498516
defer2.resolve( 2 );
499517

500518
piped2.done( function( value ) {
501-
assert.strictEqual( this, piped2,
502-
"default context updated to latest promise in the chain (without passing function)" );
519+
assert.strictEqual( this, window, ".pipe without handler does not introduce context" );
503520
assert.strictEqual( value, 2, "proper value received (without passing function)" );
504521
done.pop().call();
505522
} );
@@ -840,15 +857,13 @@ QUnit.test( "jQuery.when - joined", function( assert ) {
840857
var shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ],
841858
shouldError = willError[ id1 ] || willError[ id2 ],
842859
expected = shouldResolve ? [ 1, 1 ] : [ 0, undefined ],
843-
code = "jQuery.when( " + id1 + ", " + id2 + " )",
844-
context1 = defer1 && jQuery.isFunction( defer1.promise ) ? defer1.promise() : window,
845-
context2 = defer2 && jQuery.isFunction( defer2.promise ) ? defer2.promise() : window;
860+
code = "jQuery.when( " + id1 + ", " + id2 + " )";
846861

847862
jQuery.when( defer1, defer2 ).done( function( a, b ) {
848863
if ( shouldResolve ) {
849864
assert.deepEqual( [ a, b ], expected, code + " => resolve" );
850-
assert.strictEqual( this[ 0 ], context1, code + " => first context OK" );
851-
assert.strictEqual( this[ 1 ], context2, code + " => second context OK" );
865+
assert.strictEqual( this[ 0 ], window, code + " => first context OK" );
866+
assert.strictEqual( this[ 1 ], window, code + " => second context OK" );
852867
} else {
853868
assert.ok( false, code + " => resolve" );
854869
}

0 commit comments

Comments
 (0)