Skip to content

Instantly share code, notes, and snippets.

@A1rPun
Last active April 8, 2016 10:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save A1rPun/7cd68fe4fc6d41916051 to your computer and use it in GitHub Desktop.
Save A1rPun/7cd68fe4fc6d41916051 to your computer and use it in GitHub Desktop.
$q queue
var que = (function (q) {
/**
* Pause & queue a set of dynamically added async requests until the `resume` promise is resolved.
*
* @method que
* @param {Function} pause A function that returns a boolean which results the que instance to pause. Will be executed with every add() or resolved promise.
* @param {Function} resume A function that returns a promise which tells the que instance to resume when it resolves. It does nothing when the promise is rejected.
* @return {Object} que instance
*/
function que(pause, resume) {
this.pause = pause;
this.resume = resume;
}
que.prototype = {
queue: [],
resuming: false,
/**
* Add a function that will be executed when the que instance isn't paused.
* It returns a promise which resolves when the returning promise
* from the function is resolved.
*
* @method add
* @param {Function} fn A function that returns a promise. This will be executed when the que instance isn't paused.
* @return {Promise} The promise wrapper
*/
add: function (fn) {
var p = q.defer();
this.queue.push({
promise: p,
callback: fn
});
this.que();
return p.promise;
},
/**
* This checks whether the que instance must pause, resume or just handle the queue.
*
* @method que
* @private
*/
que: function () {
var me = this;
if (me.resuming) return;
if (me.pause()) {
me.resuming = true;
me.resume()
.finally(function () {
me.resuming = false;
me.next();
});
} else {
me.next();
}
},
/**
* Loops the queue and activates all of the waiting promises.
*
* @method next
* @private
*/
next: function () {
while (this.queue.length)
this.activate(this.queue.shift());
},
/**
* Activates the passed promise and handles the state. Arguments will be passed to the original promise callback.
*
* @method activate
* @private
*/
activate: function (obj) {
var promise = obj.callback();
promise
.then(function () {
obj.promise.resolve.apply(promise, arguments);
})
.catch(function () {
obj.promise.reject.apply(promise, arguments);
});
}
};
return que;
}($q));
function createSimplePromise(interval) {
var p = q.defer();
setTimeout(function() {
p.resolve();
}, interval);
return p.promise;
}
var mustPause = false;
var testqueue = new que(function() {
console.log('Need pause?');
return mustPause = !mustPause;
}, function() {
console.log('Try to resume');
return createSimplePromise(100, 'Try To Resume');
});
for (var i = 1, l = 10; i < l; i++)(function(b) {
testqueue.add(function() {
return createSimplePromise(b * 100, b);
}).done(function() {
console.log('Done: ' + b);
});
}(i));
createSimplePromise(2000)
.done(function() {
testqueue.add(function() {
return createSimplePromise(100)
}).done(function() {
console.log('Done: Last');
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment