From 3e8483a946853e5cef011f02282655589c5ab1c3 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Wed, 6 Jul 2016 20:45:15 -0700 Subject: [PATCH 1/3] Deferred: invoke processes in async groups instead of individually --- src/deferred.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/deferred.js b/src/deferred.js index 8139515fef..53469a552a 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -45,6 +45,9 @@ function adoptValue( value, resolve, reject ) { } } +var processQueue = []; +var processQueueTimeout; + jQuery.extend( { Deferred: function( func ) { @@ -212,12 +215,14 @@ jQuery.extend( { } }; + processQueue.push( process ); + // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if ( depth ) { - process(); + deferredTick(); } else { // Call an optional hook to record the stack, in case of exception @@ -225,7 +230,11 @@ jQuery.extend( { if ( jQuery.Deferred.getStackHook ) { process.stackTrace = jQuery.Deferred.getStackHook(); } - window.setTimeout( process ); + + // Ensure processing has been scheduled + if ( !processQueueTimeout ) { + processQueueTimeout = window.setTimeout( deferredTick ); + } } }; } @@ -385,5 +394,12 @@ jQuery.extend( { } } ); +function deferredTick() { + processQueueTimeout = undefined; + jQuery.each( processQueue.splice( 0 ), function( _, process ) { + process(); + } ); +} + return jQuery; } ); From 4bc074b3d98338743b87669a3fe6ad0ca01a09b9 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Mon, 18 Jul 2016 22:40:32 -0700 Subject: [PATCH 2/3] Deferred: ignore errors thrown in progress callbacks --- src/deferred.js | 7 ++++++- test/unit/deferred.js | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/deferred.js b/src/deferred.js index 53469a552a..9c2bf56d17 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -186,8 +186,13 @@ jQuery.extend( { }, // Only normal processors (resolve) catch and reject exceptions + // Exceptions in other cases should not effect the promise result process = special ? - mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) {} + } : function() { try { mightThrow(); diff --git a/test/unit/deferred.js b/test/unit/deferred.js index 32f3256814..466c88e5ad 100644 --- a/test/unit/deferred.js +++ b/test/unit/deferred.js @@ -372,6 +372,28 @@ QUnit.test( "jQuery.Deferred.then - deferred (progress)", function( assert ) { } ); } ); +QUnit.test( "jQuery.Deferred.then - deferred (progress) exceptions", function( assert ) { + + assert.expect( 1 ); + + var piped1, piped2, + defer = jQuery.Deferred(), + done = assert.async(); + + piped1 = defer.then( null, null, function() { + throw new Error( "You cant see me" ); + } ); + + piped2 = defer.then( null, null, function( n ) { + assert.strictEqual( n, 42, "Errors in previous notifiers don't stop other notify callbacks" ); + } ); + + piped2.then( done ); + + defer.notify( 42 ); + defer.resolve(); +} ); + QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - deferred (progress)", function( assert ) { assert.expect( 3 ); From a15233f2cfdb1c7e583cced4b5d47f1d57bd4486 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Wed, 20 Jul 2016 21:11:31 -0700 Subject: [PATCH 3/3] Deferred: specify array-splice length argument required in ES5 --- src/deferred.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deferred.js b/src/deferred.js index 9c2bf56d17..f2b7d2bc68 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -401,7 +401,7 @@ jQuery.extend( { function deferredTick() { processQueueTimeout = undefined; - jQuery.each( processQueue.splice( 0 ), function( _, process ) { + jQuery.each( processQueue.splice( 0, processQueue.length ), function( _, process ) { process(); } ); }