UNPKG

@image/packer

Version:
111 lines (110 loc) 3.5 kB
var resolveWith = function (value) { if (value && typeof value.then === 'function') { return value; } return new Promise(function (resolve) { resolve(value); }); }; /** * It limits concurrently executed promises * @example * * var queue = new Queue(1); * * queue.add(function () { * // resolve of this promise will resume next request * return downloadTarballFromGithub(url, file); * }) * .then(function (file) { * doStuffWith(file); * }); * * queue.add(function () { * return downloadTarballFromGithub(url, file); * }) * // This request will be paused * .then(function (file) { * doStuffWith(file); * }); */ var PromiseQueue = (function () { /** * @param [maxPendingPromises=Infinity] max number of concurrently executed promises * @param [maxQueuedPromises=Infinity] max number of queued promises */ function PromiseQueue(maxPendingPromises, maxQueuedPromises) { this.pendingPromises = 0; this.maxPendingPromises = typeof maxPendingPromises !== 'undefined' ? maxPendingPromises : Infinity; this.maxQueuedPromises = typeof maxQueuedPromises !== 'undefined' ? maxQueuedPromises : Infinity; this.queue = []; } PromiseQueue.prototype.add = function (promiseGenerator) { var self = this; return new Promise(function (resolve, reject) { // Do not queue to much promises if (self.queue.length >= self.maxQueuedPromises) { reject(new Error('Queue limit reached')); return; } // Add to queue self.queue.push({ promiseGenerator: promiseGenerator, resolve: resolve, reject: reject }); self._dequeue(); }); }; /** * Number of simultaneously running promises (which are resolving) */ PromiseQueue.prototype.getPendingLength = function () { return this.pendingPromises; }; /** * Number of queued promises (which are waiting) */ PromiseQueue.prototype.getQueueLength = function () { return this.queue.length; }; /** * @returns true if first item removed from queue */ PromiseQueue.prototype._dequeue = function () { var self = this; if (this.pendingPromises >= this.maxPendingPromises) { return false; } // Remove from queue var item = this.queue.shift(); if (!item) { return false; } try { this.pendingPromises++; resolveWith(item.promiseGenerator()) .then(function (value) { // It is not pending now self.pendingPromises--; // It should pass values item.resolve(value); self._dequeue(); }, function (err) { // It is not pending now self.pendingPromises--; // It should not mask errors item.reject(err); self._dequeue(); }); } catch (err) { self.pendingPromises--; item.reject(err); self._dequeue(); } return true; }; return PromiseQueue; }()); export default PromiseQueue;