@oat-sa/tao-core-sdk
Version:
Core libraries of TAO
110 lines (99 loc) • 3.68 kB
JavaScript
define(['lodash', 'core/promise', 'core/eventifier', 'core/uuid'], function (_, Promise, eventifier, uuid) { 'use strict';
_ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
Promise = Promise && Object.prototype.hasOwnProperty.call(Promise, 'default') ? Promise['default'] : Promise;
eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;
uuid = uuid && Object.prototype.hasOwnProperty.call(uuid, 'default') ? uuid['default'] : uuid;
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2017-2019 Open Assessment Technologies SA
*/
/**
* Creates a new promise queue
* @returns {promiseQueue}
*/
function promiseQueueFactory() {
//where we keep the pending promises
let queue = {};
function getId() {
const id = `promise-${uuid(6)}`;
if (typeof queue[id] === 'undefined') {
return id;
}
return getId();
}
/**
* @typedef {promiseQueue}
*/
return {
/**
* Just add another promise to the queue
* @param {Promise} promise
* @returns {promiseQueue} chains
*/
add(promise) {
queue[getId()] = promise;
return this;
},
/**
* Get the queue values
* @returns {Promise[]} the array of promises in the queue
*/
getValues() {
return _.values(queue);
},
/**
* Empty the queue
* @returns {promiseQueue} chains
*/
clear() {
queue = {};
return this;
},
/**
* Run the given promise at the end of the queue,
* @param {Function} promiseFn - a function that returns a promise
* @returns {Promise}
*/
serie(promiseFn) {
const id = getId();
//the actual queue to execute before running the given promise
const currentQueue = this.getValues();
//use an emitter to notify the promise fulfillment, internally.
const emitter = eventifier();
//add a waiting promise into the queue (for others who are calling the queue)
queue[id] = new Promise(function (resolve) {
emitter.on('fulfilled', resolve);
});
//wait for the queue,
//then run the given promise
//and resolve the waiting promise (for others)
return Promise.all(currentQueue).then(function () {
if (_.isFunction(promiseFn)) {
return promiseFn();
}
}).then(function (data) {
emitter.trigger('fulfilled');
delete queue[id];
return data;
}).catch(function (err) {
queue = {};
throw err;
});
}
};
}
return promiseQueueFactory;
});