Commit a41f2406 authored by jaubourg's avatar jaubourg

Makes Deferred implementation truly Promise/A compliant. Unit tests amended....

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/.
parent a29d4828
...@@ -609,7 +609,7 @@ jQuery.extend({ ...@@ -609,7 +609,7 @@ jQuery.extend({
} }
} else { } else {
tmp = map[ jqXHR.status ]; tmp = map[ jqXHR.status ];
jqXHR.then( tmp, tmp ); jqXHR.always( tmp );
} }
} }
return this; return this;
......
...@@ -28,15 +28,11 @@ jQuery.extend({ ...@@ -28,15 +28,11 @@ jQuery.extend({
isResolved: doneList.fired, isResolved: doneList.fired,
isRejected: failList.fired, isRejected: failList.fired,
then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
return this;
},
always: function() { always: function() {
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
return this; return this;
}, },
pipe: function( fnDone, fnFail, fnProgress ) { then: function( fnDone, fnFail, fnProgress ) {
return jQuery.Deferred(function( newDefer ) { return jQuery.Deferred(function( newDefer ) {
jQuery.each( { jQuery.each( {
done: [ fnDone, "resolve" ], done: [ fnDone, "resolve" ],
...@@ -50,7 +46,7 @@ jQuery.extend({ ...@@ -50,7 +46,7 @@ jQuery.extend({
deferred[ handler ](function() { deferred[ handler ](function() {
returned = fn.apply( this, arguments ); returned = fn.apply( this, arguments );
if ( returned && jQuery.isFunction( returned.promise ) ) { 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 { } else {
newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
} }
...@@ -74,9 +70,15 @@ jQuery.extend({ ...@@ -74,9 +70,15 @@ jQuery.extend({
return obj; return obj;
} }
}, },
deferred = promise.promise({}), deferred,
key; key;
// Keep pipe for back-compat
promise.pipe = promise.then;
// Construct deferred
deferred = promise.promise({});
for ( key in lists ) { for ( key in lists ) {
deferred[ key ] = lists[ key ].fire; deferred[ key ] = lists[ key ].fire;
deferred[ key + "With" ] = lists[ key ].fireWith; deferred[ key + "With" ] = lists[ key ].fireWith;
...@@ -127,7 +129,7 @@ jQuery.extend({ ...@@ -127,7 +129,7 @@ jQuery.extend({
if ( length > 1 ) { if ( length > 1 ) {
for ( ; i < length; i++ ) { for ( ; i < length; i++ ) {
if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { 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 { } else {
--count; --count;
} }
......
...@@ -8,32 +8,36 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) { ...@@ -8,32 +8,36 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
test("jQuery.Deferred" + withNew, function() { 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( true , "Success on resolve" );
ok( this.isResolved(), "Deferred is resolved" ); ok( this.isResolved(), "Deferred is resolved" );
strictEqual( this.state(), "resolved", "Deferred is resolved (state)" ); strictEqual( this.state(), "resolved", "Deferred is resolved (state)" );
}, function() { }).fail(function() {
ok( false , "Error on resolve" ); ok( false , "Error on resolve" );
}).always( function() { }).always(function() {
ok( true , "Always callback on resolve" ); ok( true , "Always callback on resolve" );
}); });
createDeferred().reject().then( function() { createDeferred().reject().done(function() {
ok( false , "Success on reject" ); ok( false , "Success on reject" );
}, function() { }).fail(function() {
ok( true , "Error on reject" ); ok( true , "Error on reject" );
ok( this.isRejected(), "Deferred is rejected" ); ok( this.isRejected(), "Deferred is rejected" );
strictEqual( this.state(), "rejected", "Deferred is rejected (state)" ); strictEqual( this.state(), "rejected", "Deferred is rejected (state)" );
}).always( function() { }).always(function() {
ok( true , "Always callback on reject" ); ok( true , "Always callback on reject" );
}); });
createDeferred( function( defer ) { createDeferred(function( defer ) {
ok( this === defer , "Defer passed as this & first argument" ); ok( this === defer , "Defer passed as this & first argument" );
this.resolve( "done" ); this.resolve( "done" );
}).then( function( value ) { }).done( function( value ) {
strictEqual( value , "done" , "Passed function executed" ); strictEqual( value , "done" , "Passed function executed" );
}); });
...@@ -58,7 +62,7 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) { ...@@ -58,7 +62,7 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
test( "jQuery.Deferred - chainability", function() { 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(); defer = jQuery.Deferred();
expect( methods.length ); expect( methods.length );
...@@ -69,12 +73,12 @@ test( "jQuery.Deferred - chainability", function() { ...@@ -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); expect(4);
var defer = jQuery.Deferred(), var defer = jQuery.Deferred(),
piped = defer.pipe(function( a, b ) { piped = defer.then(function( a, b ) {
return a * b; return a * b;
}), }),
value1, value1,
...@@ -96,21 +100,21 @@ test( "jQuery.Deferred.pipe - filtering (done)", function() { ...@@ -96,21 +100,21 @@ test( "jQuery.Deferred.pipe - filtering (done)", function() {
strictEqual( value2, 3, "second resolve value ok" ); strictEqual( value2, 3, "second resolve value ok" );
strictEqual( value3, 6, "result of filter ok" ); strictEqual( value3, 6, "result of filter ok" );
jQuery.Deferred().reject().pipe(function() { jQuery.Deferred().reject().then(function() {
ok( false, "pipe should not be called on reject" ); ok( false, "then should not be called on reject" );
}); });
jQuery.Deferred().resolve().pipe( jQuery.noop ).done(function( value ) { jQuery.Deferred().resolve().then( jQuery.noop ).done(function( value ) {
strictEqual( value, undefined, "pipe done callback can return undefined/null" ); 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); expect(4);
var defer = jQuery.Deferred(), var defer = jQuery.Deferred(),
piped = defer.pipe( null, function( a, b ) { piped = defer.then( null, function( a, b ) {
return a * b; return a * b;
} ), } ),
value1, value1,
...@@ -132,21 +136,21 @@ test( "jQuery.Deferred.pipe - filtering (fail)", function() { ...@@ -132,21 +136,21 @@ test( "jQuery.Deferred.pipe - filtering (fail)", function() {
strictEqual( value2, 3, "second reject value ok" ); strictEqual( value2, 3, "second reject value ok" );
strictEqual( value3, 6, "result of filter ok" ); strictEqual( value3, 6, "result of filter ok" );
jQuery.Deferred().resolve().pipe( null, function() { jQuery.Deferred().resolve().then( null, function() {
ok( false, "pipe should not be called on resolve" ); ok( false, "then should not be called on resolve" );
} ); } );
jQuery.Deferred().reject().pipe( null, jQuery.noop ).fail(function( value ) { jQuery.Deferred().reject().then( null, jQuery.noop ).fail(function( value ) {
strictEqual( value, undefined, "pipe fail callback can return undefined/null" ); 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); expect(3);
var defer = jQuery.Deferred(), var defer = jQuery.Deferred(),
piped = defer.pipe( null, null, function( a, b ) { piped = defer.then( null, null, function( a, b ) {
return a * b; return a * b;
} ), } ),
value1, value1,
...@@ -169,12 +173,12 @@ test( "jQuery.Deferred.pipe - filtering (progress)", function() { ...@@ -169,12 +173,12 @@ test( "jQuery.Deferred.pipe - filtering (progress)", function() {
strictEqual( value3, 6, "result of filter ok" ); strictEqual( value3, 6, "result of filter ok" );
}); });
test( "jQuery.Deferred.pipe - deferred (done)", function() { test( "jQuery.Deferred.then - deferred (done)", function() {
expect(3); expect(3);
var defer = jQuery.Deferred(), var defer = jQuery.Deferred(),
piped = defer.pipe(function( a, b ) { piped = defer.then(function( a, b ) {
return jQuery.Deferred(function( defer ) { return jQuery.Deferred(function( defer ) {
defer.reject( a * b ); defer.reject( a * b );
}); });
...@@ -199,12 +203,12 @@ test( "jQuery.Deferred.pipe - deferred (done)", function() { ...@@ -199,12 +203,12 @@ test( "jQuery.Deferred.pipe - deferred (done)", function() {
strictEqual( value3, 6, "result of filter ok" ); strictEqual( value3, 6, "result of filter ok" );
}); });
test( "jQuery.Deferred.pipe - deferred (fail)", function() { test( "jQuery.Deferred.then - deferred (fail)", function() {
expect(3); expect(3);
var defer = jQuery.Deferred(), var defer = jQuery.Deferred(),
piped = defer.pipe( null, function( a, b ) { piped = defer.then( null, function( a, b ) {
return jQuery.Deferred(function( defer ) { return jQuery.Deferred(function( defer ) {
defer.resolve( a * b ); defer.resolve( a * b );
}); });
...@@ -229,12 +233,12 @@ test( "jQuery.Deferred.pipe - deferred (fail)", function() { ...@@ -229,12 +233,12 @@ test( "jQuery.Deferred.pipe - deferred (fail)", function() {
strictEqual( value3, 6, "result of filter ok" ); strictEqual( value3, 6, "result of filter ok" );
}); });
test( "jQuery.Deferred.pipe - deferred (progress)", function() { test( "jQuery.Deferred.then - deferred (progress)", function() {
expect(3); expect(3);
var defer = jQuery.Deferred(), 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 ) { return jQuery.Deferred(function( defer ) {
defer.resolve( a * b ); defer.resolve( a * b );
}); });
...@@ -259,13 +263,13 @@ test( "jQuery.Deferred.pipe - deferred (progress)", function() { ...@@ -259,13 +263,13 @@ test( "jQuery.Deferred.pipe - deferred (progress)", function() {
strictEqual( value3, 6, "result of filter ok" ); strictEqual( value3, 6, "result of filter ok" );
}); });
test( "jQuery.Deferred.pipe - context", function() { test( "jQuery.Deferred.then - context", function() {
expect(4); expect(4);
var context = {}; var context = {};
jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe(function( value ) { jQuery.Deferred().resolveWith( context, [ 2 ] ).then(function( value ) {
return value * 3; return value * 3;
}).done(function( value ) { }).done(function( value ) {
strictEqual( this, context, "custom context correctly propagated" ); strictEqual( this, context, "custom context correctly propagated" );
...@@ -273,7 +277,7 @@ test( "jQuery.Deferred.pipe - context", function() { ...@@ -273,7 +277,7 @@ test( "jQuery.Deferred.pipe - context", function() {
}); });
var defer = jQuery.Deferred(), var defer = jQuery.Deferred(),
piped = defer.pipe(function( value ) { piped = defer.then(function( value ) {
return value * 3; return value * 3;
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment