Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
127
rated 0 times [  133] [ 6]  / answers: 1 / hits: 141826  / 10 Years ago, wed, july 9, 2014, 12:00:00

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?


More From » node.js

 Answers
17

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'));

[#70261] Monday, July 7, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
jenna

Total Points: 706
Total Questions: 107
Total Answers: 106

Location: Azerbaijan
Member since Tue, Sep 21, 2021
3 Years ago
;