Files
pathfinder/js/app/promises/promise.queue.js
Mark Friedrich 0c3d57e833 - BC Break: Required _PHP_ version changed >=7.1>=7.2
- NEW "plugin API" for custom UI modules, closed #913
- NEW live "Killstream" for killboard module, closed #909
- NEW "custom layout" UI settings, closed #470
2020-02-01 12:40:17 +01:00

82 lines
2.3 KiB
JavaScript

define([], () => {
'use strict';
/**
* sequential promise queue
* @see https://medium.com/@karenmarkosyan/how-to-manage-promises-into-dynamic-queue-with-vanilla-javascript-9d0d1f8d4df5
* @see https://codepen.io/exodus4d/pen/QWwgKay
*/
return class Queue {
constructor() {
this._queue = [];
this._pendingPromise = false;
this._stop = false;
}
/**
* wraps a promise that needs to be sequentially resolved
* -> dequeue() process starts immediately (if not already pending)
* @param promise
* @param {'end'|'start'} position
* @param data
* @returns {Promise}
*/
enqueue(promise, position = 'end', data = null) {
return new Promise((resolve, reject) => {
this._queue[position === 'end' ? 'push' : 'unshift']({
promise,
resolve,
reject,
data,
});
this.dequeue();
});
}
/**
* resolve promise queue recursive until queue is empty
* @returns {boolean}
*/
dequeue() {
if (this._pendingPromise) {
return false;
}
if (this._stop) {
this._queue = [];
this._stop = false;
return false;
}
let item = this._queue.shift();
if (!item) {
return false;
}
try {
this._pendingPromise = true;
item.promise()
.then((value) => {
this._pendingPromise = false;
item.resolve(value);
this.dequeue();
})
.catch(err => {
this._pendingPromise = false;
item.reject(err);
this.dequeue();
});
} catch (err) {
this._pendingPromise = false;
item.reject(err);
this.dequeue();
}
return true;
}
filterQueue(callback) {
return this._queue.filter(callback);
}
};
});