ES6 client/galaxy/scripts/utils/ajax-queue.js

- Use ``class``, ``super``, ``static``, and ``constructor`` to clean up object declaration.
- Eliminate ``self``.
This commit is contained in:
John Chilton
2017-11-05 11:18:51 -05:00
parent ed0ac48985
commit b8a33ed500
6 changed files with 127 additions and 144 deletions
+122 -139
View File
@@ -8,119 +8,114 @@
* @constructor accepts a list of functions and automatically begins
* processing them
*/
function AjaxQueue(initialFunctions) {
//TODO: possibly rename to DeferredQueue
var self = this;
/** the main deferred for the entire queue - note: also sends notifications of progress */
self.deferred = jQuery.Deferred();
/** the queue array of functions */
self.queue = [];
/** cache the response from each deferred call - error or success */
self.responses = [];
/** total number of fn's to process */
self.numToProcess = 0;
/** is the queue processing/waiting for any calls to return? */
self.running = false;
class AjaxQueue {
constructor(initialFunctions) {
/** the main deferred for the entire queue - note: also sends notifications of progress */
this.deferred = jQuery.Deferred();
/** the queue array of functions */
this.queue = [];
/** cache the response from each deferred call - error or success */
this.responses = [];
/** total number of fn's to process */
this.numToProcess = 0;
/** is the queue processing/waiting for any calls to return? */
this.running = false;
self.init(initialFunctions || []);
self.start();
this.init(initialFunctions || []);
this.start();
}
return self;
}
/** add all fns in initialFunctions (if any) to the queue */
init(initialFunctions) {
initialFunctions.forEach(fn => {
this.add(fn);
});
}
/** add all fns in initialFunctions (if any) to the queue */
AjaxQueue.prototype.init = function init(initialFunctions) {
var self = this;
initialFunctions.forEach(fn => {
self.add(fn);
});
};
add(fn) {
var index = this.queue.length;
this.numToProcess += 1;
/** add a fn to the queue */
AjaxQueue.prototype.add = function add(fn) {
//console.debug( 'AjaxQueue.prototype.add:', fn );
var self = this;
var index = this.queue.length;
this.numToProcess += 1;
this.queue.push(() => {
var fnIndex = index;
var xhr = fn();
// if successful, notify using the deferred to allow tracking progress
xhr.done(response => {
self.deferred.notify({
curr: fnIndex,
total: self.numToProcess,
response: response
this.queue.push(() => {
var fnIndex = index;
var xhr = fn();
// if successful, notify using the deferred to allow tracking progress
xhr.done(response => {
this.deferred.notify({
curr: fnIndex,
total: this.numToProcess,
response: response
});
});
// (regardless of previous error or success) if not last ajax call, shift and call the next
// if last fn, resolve deferred
xhr.always(response => {
this.responses.push(response);
if (this.queue.length) {
this.queue.shift()();
} else {
this.stop();
}
});
});
// (regardless of previous error or success) if not last ajax call, shift and call the next
// if last fn, resolve deferred
xhr.always(response => {
self.responses.push(response);
if (self.queue.length) {
self.queue.shift()();
} else {
self.stop();
}
});
});
return this;
};
/** start processing the queue */
AjaxQueue.prototype.start = function start() {
if (this.queue.length) {
this.running = true;
this.queue.shift()();
return this;
}
return this;
};
/** stop the queue
* @param {boolean} causeFail cause an error/fail on the main deferred
* @param {String} msg message to send when rejecting the main deferred
*/
AjaxQueue.prototype.stop = function stop(causeFail, msg) {
//TODO: doesn't abort current call
this.running = false;
this.queue = [];
if (causeFail) {
//TODO: spliced args instead
this.deferred.reject(msg);
} else {
this.deferred.resolve(this.responses);
start() {
if (this.queue.length) {
this.running = true;
this.queue.shift()();
}
return this;
}
this.numToProcess = 0;
this.deferred = jQuery.Deferred();
return this;
};
// only a handful of the deferred interface for now - possible YAGNI
/** implement done from the jq deferred interface */
AjaxQueue.prototype.done = function done(fn) {
return this.deferred.done(fn);
};
/** implement fail from the jq deferred interface */
AjaxQueue.prototype.fail = function fail(fn) {
return this.deferred.fail(fn);
};
/** implement always from the jq deferred interface */
AjaxQueue.prototype.always = function always(fn) {
return this.deferred.always(fn);
};
/** implement progress from the jq deferred interface */
AjaxQueue.prototype.progress = function progress(fn) {
return this.deferred.progress(fn);
};
/** stop the queue
* @param {boolean} causeFail cause an error/fail on the main deferred
* @param {String} msg message to send when rejecting the main deferred
*/
stop(causeFail, msg) {
//TODO: doesn't abort current call
this.running = false;
this.queue = [];
if (causeFail) {
//TODO: spliced args instead
this.deferred.reject(msg);
} else {
this.deferred.resolve(this.responses);
}
this.numToProcess = 0;
this.deferred = jQuery.Deferred();
return this;
}
/** shortcut constructor / fire and forget
* @returns {Deferred} the queue's main deferred
*/
AjaxQueue.create = function create(initialFunctions) {
return new AjaxQueue(initialFunctions).deferred;
};
// only a handful of the deferred interface for now - possible YAGNI
/** implement done from the jq deferred interface */
done(fn) {
return this.deferred.done(fn);
}
/** implement fail from the jq deferred interface */
fail(fn) {
return this.deferred.fail(fn);
}
/** implement always from the jq deferred interface */
always(fn) {
return this.deferred.always(fn);
}
/** implement progress from the jq deferred interface */
progress(fn) {
return this.deferred.progress(fn);
}
/** shortcut constructor / fire and forget
* @returns {Deferred} the queue's main deferred
*/
static create(initialFunctions) {
return new AjaxQueue(initialFunctions).deferred;
}
}
//=============================================================================
/** @class NamedAjaxQueue
@@ -133,44 +128,32 @@ AjaxQueue.create = function create(initialFunctions) {
* { name: some unique id,
* fn: the deferring fn or ajax call }
*/
function NamedAjaxQueue(initialFunctions) {
var self = this;
self.names = {};
AjaxQueue.call(this, initialFunctions);
return self;
class NamedAjaxQueue extends AjaxQueue {
/** add the obj.fn to the queue if obj.name hasn't been used before */
add(obj) {
if (!(obj.hasOwnProperty("name") && obj.hasOwnProperty("fn"))) {
throw new Error(`NamedAjaxQueue.add requires an object with both "name" and "fn": ${JSON.stringify(obj)}`);
}
if (this.names.hasOwnProperty(obj.name)) {
//console.warn( 'name has been used:', obj.name );
return;
}
this.names[obj.name] = true;
return super.add(obj.fn);
}
clear() {
this.names = {};
return this;
}
/** shortcut constructor / fire and forget
* @returns {Deferred} the queue's main deferred
*/
static create(initialFunctions) {
return new NamedAjaxQueue(initialFunctions).deferred;
}
}
NamedAjaxQueue.prototype = new AjaxQueue();
NamedAjaxQueue.prototype.constructor = NamedAjaxQueue;
/** add the obj.fn to the queue if obj.name hasn't been used before */
NamedAjaxQueue.prototype.add = function add(obj) {
//console.debug( 'NamedAjaxQueue.adding:', obj )
//console.debug( 'NamedAjaxQueue.prototype.add:', obj );
if (!(obj.hasOwnProperty("name") && obj.hasOwnProperty("fn"))) {
throw new Error(`NamedAjaxQueue.add requires an object with both "name" and "fn": ${JSON.stringify(obj)}`);
}
if (this.names.hasOwnProperty(obj.name)) {
//console.warn( 'name has been used:', obj.name );
return;
}
this.names[obj.name] = true;
//console.debug( '\t names: ', this.names )
return AjaxQueue.prototype.add.call(this, obj.fn);
//console.debug( '\t queue: ', this.queue.length );
};
/** override to remove names */
NamedAjaxQueue.prototype.clear = function clear() {
this.names = {};
return this;
};
/** shortcut constructor / fire and forget
* @returns {Deferred} the queue's main deferred
*/
NamedAjaxQueue.create = function create(initialFunctions) {
return new NamedAjaxQueue(initialFunctions).deferred;
};
//=============================================================================
export default {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define("utils/ajax-queue",["exports"],function(e){"use strict";function t(e){var t=this;return t.deferred=jQuery.Deferred(),t.queue=[],t.responses=[],t.numToProcess=0,t.running=!1,t.init(e||[]),t.start(),t}function r(e){var r=this;return r.names={},t.call(this,e),r}Object.defineProperty(e,"__esModule",{value:!0}),t.prototype.init=function(e){var t=this;e.forEach(function(e){t.add(e)})},t.prototype.add=function(e){var t=this,r=this.queue.length;return this.numToProcess+=1,this.queue.push(function(){var n=r,s=e();s.done(function(e){t.deferred.notify({curr:n,total:t.numToProcess,response:e})}),s.always(function(e){t.responses.push(e),t.queue.length?t.queue.shift()():t.stop()})}),this},t.prototype.start=function(){return this.queue.length&&(this.running=!0,this.queue.shift()()),this},t.prototype.stop=function(e,t){return this.running=!1,this.queue=[],e?this.deferred.reject(t):this.deferred.resolve(this.responses),this.numToProcess=0,this.deferred=jQuery.Deferred(),this},t.prototype.done=function(e){return this.deferred.done(e)},t.prototype.fail=function(e){return this.deferred.fail(e)},t.prototype.always=function(e){return this.deferred.always(e)},t.prototype.progress=function(e){return this.deferred.progress(e)},t.create=function(e){return new t(e).deferred},(r.prototype=new t).constructor=r,r.prototype.add=function(e){if(!e.hasOwnProperty("name")||!e.hasOwnProperty("fn"))throw new Error('NamedAjaxQueue.add requires an object with both "name" and "fn": '+JSON.stringify(e));if(!this.names.hasOwnProperty(e.name))return this.names[e.name]=!0,t.prototype.add.call(this,e.fn)},r.prototype.clear=function(){return this.names={},this},r.create=function(e){return new r(e).deferred},e.default={AjaxQueue:t,NamedAjaxQueue:r}});
define("utils/ajax-queue",["exports"],function(e){"use strict";function t(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var u=function e(t,r,n){null===t&&(t=Function.prototype);var u=Object.getOwnPropertyDescriptor(t,r);if(void 0===u){var o=Object.getPrototypeOf(t);return null===o?void 0:e(o,r,n)}if("value"in u)return u.value;var i=u.get;if(void 0!==i)return i.call(n)},o=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),i=function(){function e(t){n(this,e),this.deferred=jQuery.Deferred(),this.queue=[],this.responses=[],this.numToProcess=0,this.running=!1,this.init(t||[]),this.start()}return o(e,[{key:"init",value:function(e){var t=this;e.forEach(function(e){t.add(e)})}},{key:"add",value:function(e){var t=this,r=this.queue.length;return this.numToProcess+=1,this.queue.push(function(){var n=r,u=e();u.done(function(e){t.deferred.notify({curr:n,total:t.numToProcess,response:e})}),u.always(function(e){t.responses.push(e),t.queue.length?t.queue.shift()():t.stop()})}),this}},{key:"start",value:function(){return this.queue.length&&(this.running=!0,this.queue.shift()()),this}},{key:"stop",value:function(e,t){return this.running=!1,this.queue=[],e?this.deferred.reject(t):this.deferred.resolve(this.responses),this.numToProcess=0,this.deferred=jQuery.Deferred(),this}},{key:"done",value:function(e){return this.deferred.done(e)}},{key:"fail",value:function(e){return this.deferred.fail(e)}},{key:"always",value:function(e){return this.deferred.always(e)}},{key:"progress",value:function(e){return this.deferred.progress(e)}}],[{key:"create",value:function(t){return new e(t).deferred}}]),e}(),s=function(e){function s(){return n(this,s),t(this,(s.__proto__||Object.getPrototypeOf(s)).apply(this,arguments))}return r(s,i),o(s,[{key:"add",value:function(e){if(!e.hasOwnProperty("name")||!e.hasOwnProperty("fn"))throw new Error('NamedAjaxQueue.add requires an object with both "name" and "fn": '+JSON.stringify(e));if(!this.names.hasOwnProperty(e.name))return this.names[e.name]=!0,u(s.prototype.__proto__||Object.getPrototypeOf(s.prototype),"add",this).call(this,e.fn)}},{key:"clear",value:function(){return this.names={},this}}],[{key:"create",value:function(e){return new s(e).deferred}}]),s}();e.default={AjaxQueue:i,NamedAjaxQueue:s}});
//# sourceMappingURL=../../maps/utils/ajax-queue.js.map