Correct way to write loops for promise.

bluebird, javascript, node.js, promise

Solution

I don't think it guarantees the order of calling logger.log(res);

Actually, it does. That statement is executed before the `resolve` call.

Any suggestions?

Lots. The most important is your use of the create-promise-manually antipattern - just do only

promiseWhile(…, function() {
    return db.getUser(email)
             .then(function(res) { 
                 logger.log(res); 
                 count++;
             });
})…

Second, that `while` function could be simplified a lot:

var promiseWhile = Promise.method(function(condition, action) {
    if (!condition()) return;
    return action().then(promiseWhile.bind(null, condition, action));
});

Third, I would not use a `while` loop (with a closure variable) but a `for` loop:

var promiseFor = Promise.method(function(condition, action, value) {
    if (!condition(value)) return value;
    return action(value).then(promiseFor.bind(null, condition, action));
});

promiseFor(function(count) {
    return count < 10;
}, function(count) {
    return db.getUser(email)
             .then(function(res) { 
                 logger.log(res); 
                 return ++count;
             });
}, 0).then(console.log.bind(console, 'all done'));

Problem

How to correctly construct a loop to make sure the following promise call and the chained logger.log(res) runs synchronously through iteration? (bluebird) ``` db.getUser(email).then(function(res) { logger.log(res); }); // this is a promise ``` I tried the following way (method from http://blog.victorquinn.com/javascript-promise-while-loop ) ``` var Promise = require('bluebird'); var promiseWhile = function(condition, action) { var resolver = Promise.defer(); var loop = function() { if (!condition()) return resolver.resolve(); return Promise.cast(action()) .then(loop) .catch(resolver.reject); }; process.nextTick(loop); return resolver.promise; }); var count = 0; promiseWhile(function() { return count < 10; }, function() { return new Promise(function(resolve, reject) { db.getUser(email) .then(function(res) { logger.log(res); count++; resolve(); }); }); }).then(function() { console.log('all done'); }); ``` Although it seems to work, but I don't think it guarantees the order of calling logger.log(res); Any suggestions?

Original source

Related problems