From: jaubourg Date: Sun, 1 Apr 2012 23:29:39 +0000 (+0200) Subject: Makes Deferred implementation truly Promise/A compliant. Unit tests amended. Actually... X-Git-Tag: 1.8b1~229^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a41f2406748e3113751ab1e5b5d990d9144123fc;p=jquery.git Makes Deferred implementation truly Promise/A compliant. Unit tests amended. Actually few changes required in jQuery's own source and we gained 8 bytes minified gzipped \o/. --- diff --git a/src/ajax.js b/src/ajax.js index 2bcc1d0a2..b241b257e 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -609,7 +609,7 @@ jQuery.extend({ } } else { tmp = map[ jqXHR.status ]; - jqXHR.then( tmp, tmp ); + jqXHR.always( tmp ); } } return this; diff --git a/src/deferred.js b/src/deferred.js index c97084b70..ddc324738 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -28,15 +28,11 @@ jQuery.extend({ isResolved: doneList.fired, isRejected: failList.fired, - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, always: function() { deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); return this; }, - pipe: function( fnDone, fnFail, fnProgress ) { + then: function( fnDone, fnFail, fnProgress ) { return jQuery.Deferred(function( newDefer ) { jQuery.each( { done: [ fnDone, "resolve" ], @@ -50,7 +46,7 @@ jQuery.extend({ deferred[ handler ](function() { returned = fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + returned.promise().done( newDefer.resolve ).fail( newDefer.reject ).progress( newDefer.notify ); } else { newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); } @@ -74,9 +70,15 @@ jQuery.extend({ return obj; } }, - deferred = promise.promise({}), + deferred, key; + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Construct deferred + deferred = promise.promise({}); + for ( key in lists ) { deferred[ key ] = lists[ key ].fire; deferred[ key + "With" ] = lists[ key ].fireWith; @@ -127,7 +129,7 @@ jQuery.extend({ if ( length > 1 ) { for ( ; i < length; i++ ) { if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + args[ i ].promise().done( resolveFunc(i) ).fail( deferred.reject ).progress( progressFunc(i) ); } else { --count; } diff --git a/test/unit/deferred.js b/test/unit/deferred.js index 4a50da2c1..7ff274d56 100644 --- a/test/unit/deferred.js +++ b/test/unit/deferred.js @@ -8,32 +8,36 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) { test("jQuery.Deferred" + withNew, function() { - expect( 22 ); + expect( 23 ); - createDeferred().resolve().then( function() { + var defer = createDeferred(); + + strictEqual( defer.pipe, defer.then, "pipe is an alias of then" ); + + createDeferred().resolve().done(function() { ok( true , "Success on resolve" ); ok( this.isResolved(), "Deferred is resolved" ); strictEqual( this.state(), "resolved", "Deferred is resolved (state)" ); - }, function() { + }).fail(function() { ok( false , "Error on resolve" ); - }).always( function() { + }).always(function() { ok( true , "Always callback on resolve" ); }); - createDeferred().reject().then( function() { + createDeferred().reject().done(function() { ok( false , "Success on reject" ); - }, function() { + }).fail(function() { ok( true , "Error on reject" ); ok( this.isRejected(), "Deferred is rejected" ); strictEqual( this.state(), "rejected", "Deferred is rejected (state)" ); - }).always( function() { + }).always(function() { ok( true , "Always callback on reject" ); }); - createDeferred( function( defer ) { + createDeferred(function( defer ) { ok( this === defer , "Defer passed as this & first argument" ); this.resolve( "done" ); - }).then( function( value ) { + }).done( function( value ) { strictEqual( value , "done" , "Passed function executed" ); }); @@ -58,7 +62,7 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) { test( "jQuery.Deferred - chainability", function() { - var methods = "resolve reject notify resolveWith rejectWith notifyWith done fail progress then always".split( " " ), + var methods = "resolve reject notify resolveWith rejectWith notifyWith done fail progress always".split( " " ), defer = jQuery.Deferred(); expect( methods.length ); @@ -69,12 +73,12 @@ test( "jQuery.Deferred - chainability", function() { }); }); -test( "jQuery.Deferred.pipe - filtering (done)", function() { +test( "jQuery.Deferred.then - filtering (done)", function() { expect(4); var defer = jQuery.Deferred(), - piped = defer.pipe(function( a, b ) { + piped = defer.then(function( a, b ) { return a * b; }), value1, @@ -96,21 +100,21 @@ test( "jQuery.Deferred.pipe - filtering (done)", function() { strictEqual( value2, 3, "second resolve value ok" ); strictEqual( value3, 6, "result of filter ok" ); - jQuery.Deferred().reject().pipe(function() { - ok( false, "pipe should not be called on reject" ); + jQuery.Deferred().reject().then(function() { + ok( false, "then should not be called on reject" ); }); - jQuery.Deferred().resolve().pipe( jQuery.noop ).done(function( value ) { - strictEqual( value, undefined, "pipe done callback can return undefined/null" ); + jQuery.Deferred().resolve().then( jQuery.noop ).done(function( value ) { + strictEqual( value, undefined, "then done callback can return undefined/null" ); }); }); -test( "jQuery.Deferred.pipe - filtering (fail)", function() { +test( "jQuery.Deferred.then - filtering (fail)", function() { expect(4); var defer = jQuery.Deferred(), - piped = defer.pipe( null, function( a, b ) { + piped = defer.then( null, function( a, b ) { return a * b; } ), value1, @@ -132,21 +136,21 @@ test( "jQuery.Deferred.pipe - filtering (fail)", function() { strictEqual( value2, 3, "second reject value ok" ); strictEqual( value3, 6, "result of filter ok" ); - jQuery.Deferred().resolve().pipe( null, function() { - ok( false, "pipe should not be called on resolve" ); + jQuery.Deferred().resolve().then( null, function() { + ok( false, "then should not be called on resolve" ); } ); - jQuery.Deferred().reject().pipe( null, jQuery.noop ).fail(function( value ) { - strictEqual( value, undefined, "pipe fail callback can return undefined/null" ); + jQuery.Deferred().reject().then( null, jQuery.noop ).fail(function( value ) { + strictEqual( value, undefined, "then fail callback can return undefined/null" ); }); }); -test( "jQuery.Deferred.pipe - filtering (progress)", function() { +test( "jQuery.Deferred.then - filtering (progress)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.pipe( null, null, function( a, b ) { + piped = defer.then( null, null, function( a, b ) { return a * b; } ), value1, @@ -169,12 +173,12 @@ test( "jQuery.Deferred.pipe - filtering (progress)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.pipe - deferred (done)", function() { +test( "jQuery.Deferred.then - deferred (done)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.pipe(function( a, b ) { + piped = defer.then(function( a, b ) { return jQuery.Deferred(function( defer ) { defer.reject( a * b ); }); @@ -199,12 +203,12 @@ test( "jQuery.Deferred.pipe - deferred (done)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.pipe - deferred (fail)", function() { +test( "jQuery.Deferred.then - deferred (fail)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.pipe( null, function( a, b ) { + piped = defer.then( null, function( a, b ) { return jQuery.Deferred(function( defer ) { defer.resolve( a * b ); }); @@ -229,12 +233,12 @@ test( "jQuery.Deferred.pipe - deferred (fail)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.pipe - deferred (progress)", function() { +test( "jQuery.Deferred.then - deferred (progress)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.pipe( null, null, function( a, b ) { + piped = defer.then( null, null, function( a, b ) { return jQuery.Deferred(function( defer ) { defer.resolve( a * b ); }); @@ -259,13 +263,13 @@ test( "jQuery.Deferred.pipe - deferred (progress)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.pipe - context", function() { +test( "jQuery.Deferred.then - context", function() { expect(4); var context = {}; - jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe(function( value ) { + jQuery.Deferred().resolveWith( context, [ 2 ] ).then(function( value ) { return value * 3; }).done(function( value ) { strictEqual( this, context, "custom context correctly propagated" ); @@ -273,7 +277,7 @@ test( "jQuery.Deferred.pipe - context", function() { }); var defer = jQuery.Deferred(), - piped = defer.pipe(function( value ) { + piped = defer.then(function( value ) { return value * 3; });