const defaultOrderRegistry = {}; function wbApplyPromiseOrdering(prom, orderRegistry) { let orderId; if (!orderRegistry) orderRegistry = defaultOrderRegistry; if (Object.keys(orderRegistry).length === 0) { orderRegistry.started = 0; orderRegistry.pendingCompletion = {}; orderRegistry.completed = { 0: true }; } orderRegistry.started += 1; orderId = orderRegistry.started; // console.log('New orderId: ' + orderId); const orderCallback = ((isCatch, payload) => { // console.log('orderId: ' + orderId + // ', pendingCompletion: ' + Object.keys(orderRegistry.pendingCompletion) + // ', completed: ' + Object.keys(orderRegistry.completed)); if ((orderId - 1) in orderRegistry.completed) { // console.log('Running: ' + orderId); orderRegistry.completed[orderId] = true; delete orderRegistry.pendingCompletion[orderId]; const keys = Object.keys(orderRegistry.pendingCompletion); keys.sort((a, b) => (a - b)); keys.map(k => { if ((k - 1) in orderRegistry.completed) { // console.log('Running: ' + k); orderRegistry.pendingCompletion[k](); orderRegistry.completed[k] = true; delete orderRegistry.pendingCompletion[k]; } }); if (orderRegistry.started in orderRegistry.completed) { // console.log('Garbage collect'); orderRegistry.started = 0; orderRegistry.completed = { 0: true }; } if (isCatch) throw payload; else return payload; } const prom_1 = new Promise((accept, reject) => { orderRegistry.pendingCompletion[orderId] = (() => (isCatch ? reject(payload) : accept(payload))); }); return prom_1; }); prom = prom.then(xhr => orderCallback(false, xhr)); prom = prom.catch(e => orderCallback(true, e)); return prom; } export default wbApplyPromiseOrdering;