Mooeypoo has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/222157

Change subject: Add a Prioritizer tool to oojs
......................................................................

Add a Prioritizer tool to oojs

Add a prioritizer tool to oojs, to handle a queue of multiple
promise in rapid succession. The prioritizer will always dump the
previous promises and keep only the latest one. This is especially
useful for cases where promises are added in rapid succession, such
as in ooui's InputWidget validation method.

Change-Id: I953220e87c5f2180a6db443da236dff139e34f55
---
M Gruntfile.js
A src/Prioritizer.js
A tests/unit/Prioritizer.test.js
3 files changed, 114 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/oojs/core refs/changes/57/222157/1

diff --git a/Gruntfile.js b/Gruntfile.js
index 9f48722..54e8e8c 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -39,6 +39,7 @@
                                        'src/EventEmitter.js',
                                        'src/Registry.js',
                                        'src/Factory.js',
+                                       'src/Prioritizer.js',
                                        'src/export.js',
                                        'src/outro.js.txt'
                                ]
@@ -55,6 +56,7 @@
                                        'src/EventEmitter.js',
                                        'src/Registry.js',
                                        'src/Factory.js',
+                                       'src/Prioritizer.js',
                                        'src/export.js',
                                        'src/outro.js.txt'
                                ]
diff --git a/src/Prioritizer.js b/src/Prioritizer.js
new file mode 100644
index 0000000..d2f0ff9
--- /dev/null
+++ b/src/Prioritizer.js
@@ -0,0 +1,63 @@
+/**
+ * Prioritizes promises
+ *
+ * @class
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ */
+oo.Prioritizer = function () {
+       // Mixin constructors
+       oo.EventEmitter.call( this );
+
+       // Properties
+       this.promise = null;
+};
+
+/* Setup */
+
+oo.initClass( oo.Prioritizer );
+oo.mixinClass( oo.Prioritizer, oo.EventEmitter );
+
+/* Events */
+
+/**
+ * @event The priority promise has been resolved
+ */
+
+/**
+ * @event The priority promise has been rejected
+ */
+
+/**
+ * @event The priority promise has been reprioritized
+ * @param {jQuery.Promise} promise Promise is being reprioritized
+ */
+
+/* Methods */
+
+/**
+ * Replaces the priority promise with a new one.
+ *
+ * @param {jQuery.Promise} promise Promise to prioritize
+ */
+oo.Prioritizer.prototype.prioritize = function ( promise ) {
+       var prioritizer = this;
+
+       if ( this.promise ) {
+               this.emit( 'abort', this.promise );
+       }
+       this.promise = promise;
+       promise.then(
+               function () {
+                       if ( prioritizer.promise === promise ) {
+                               prioritizer.emit.apply( prioritizer, [ 'done' 
].concat( arguments ) );
+                       }
+               },
+               function () {
+                       if ( prioritizer.promise === promise ) {
+                               prioritizer.emit.apply( prioritizer, [ 'fail' 
].concat( arguments ) );
+                       }
+               }
+       );
+};
diff --git a/tests/unit/Prioritizer.test.js b/tests/unit/Prioritizer.test.js
new file mode 100644
index 0000000..f5d0286
--- /dev/null
+++ b/tests/unit/Prioritizer.test.js
@@ -0,0 +1,49 @@
+/*global Promise, window */
+( function ( oo ) {
+       QUnit.module( 'Prioritizer' );
+
+       // Don't run this test if the environment doesn't
+       // recognize 'Promise'. This happens in PhantomJS,
+       // so the test will only run in chrome and firefox
+       // tests.
+       if ( typeof Promise === 'undefined' ) {
+               return;
+       }
+
+       QUnit.test( 'prioritize', 1, function ( assert ) {
+               var i, testRunner,
+                       numPromises = 5,
+                       done = assert.async(),
+                       Tester = function Tester() {
+                               // Properties
+                               this.prioritizer = new oo.Prioritizer();
+
+                               // Events
+                               this.prioritizer.connect( this, {
+                                       done: 'onPrioritizerDone'
+                               } );
+                       };
+
+               Tester.prototype.prioritize = function ( value ) {
+                       var promise = new Promise( function ( resolve ) {
+                                       window.setTimeout( function () {
+                                               resolve( value );
+                                       }, 0 );
+                               } );
+
+                       this.prioritizer.prioritize( promise );
+               };
+               Tester.prototype.onPrioritizerDone = function ( data ) {
+                       assert.equal( data[0], numPromises, 'Only the last 
promise ran.' );
+                       done();
+               };
+
+               // Create the test
+               testRunner = new Tester();
+
+               // Create multiple promises
+               for ( i = 1; i <= numPromises; i++ ) {
+                       testRunner.prioritize( i );
+               }
+       } );
+}( OO ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/222157
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I953220e87c5f2180a6db443da236dff139e34f55
Gerrit-PatchSet: 1
Gerrit-Project: oojs/core
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <mor...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to