Skip to content

Instantly share code, notes, and snippets.

@neilk
Last active January 23, 2017 09:39
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neilk/6431795 to your computer and use it in GitHub Desktop.
Save neilk/6431795 to your computer and use it in GitHub Desktop.
Using Q.js, a while loop where the condition is itself a promise
'use strict';
var Q = require('q');
// `condition` is a function that returns a boolean
// `body` is a function that returns a promise
// returns a promise for the completion of the loop
function promiseWhile(condition, body) {
var done = Q.defer();
function loop() {
// When the result of calling `condition` is no longer true, we are
// done.
if (!condition()) return done.resolve();
// Use `when`, in case `body` does not return a promise.
// When it completes loop again otherwise, if it fails, reject the
// done promise
Q.when(body(), loop, done.reject);
}
// Start running the loop in the next tick so that this function is
// completely async. It would be unexpected if `body` was called
// synchronously the first time.
Q.nextTick(loop);
// The promise
return done.promise;
}
// Similar to above but the condition is now a promise
function promiseWhilePromise(condition, body) {
var deferred = Q.defer();
function loop() {
// When the result of calling `condition` is no longer true, we are
// done.
condition().then(function(bool) {
if (!bool) {
return deferred.resolve();
} else {
// Use `when`, in case `body` does not return a promise.
// When it completes loop again otherwise, if it fails, reject the
// done promise
return Q.when(body(), loop, deferred.reject);
}
});
}
// Start running the loop in the next tick so that this function is
// completely async. It would be unexpected if `body` was called
// synchronously the first time.
Q.nextTick(loop);
// The promise
return deferred.promise;
}
// Usage
var index = 1;
function conditionP() {
var deferred = Q.defer();
Q.delay(500).then(function() {
deferred.resolve(index <= 5);
});
// reject?
return deferred.promise;
}
function work() {
console.log(index);
index++;
return Q.delay(500); // arbitrary async
}
promiseWhilePromise(conditionP, work).then(function () {
console.log("done");
}).done();
Copy link

ghost commented Jan 23, 2017

While running those loop, we do have some SIGABRT which cause server to restart. I didn't found a way to fix the problem. I suspect problems comes from Q library itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment