Reputation: 23276
Loops are blocking. They seem indifferent to the idea of Node.JS. How to handle the flow where a for
loop or a while
loop seems to be the best option.
For example, if I want to print a table of a random number upto number * 1000
, I would want to use the for
loop. Is there a special way to handle this in Node.JS?
Upvotes: 2
Views: 768
Reputation: 7732
If you are doing loops on data in memory (for example, you want to go through an array and add a prop to all objects), loops will work normally, but if you need to do something inside the loop like save values to a DB, you will run into some issues.
I realize this isn't exactly the answer, but it's a suggestion that may help someone. I found one of the easiest ways to deal with this issue is using rate limiter with a forEach (I don't like really promises). This also gives the added benefit of having the option to process things in parallel, but only move on when everything is done: https://github.com/jhurliman/node-rate-limiter
var RateLimiter = require('limiter').RateLimiter;
var limiter = new RateLimiter(1, 5);
exports.saveFile = function (myArray, next) {
var completed = 0;
var totalFiles = myArray.length;
myArray.forEach(function (item) {
limiter.removeTokens(1, function () {
//call some async function
saveAndLog(item, function (err, result) {
//check for errors
completed++;
if (completed == totalFiles) {
//call next function
exports.process();
}
});
});
});
};
Upvotes: -1
Reputation: 3340
Loops are not per se bad, but it depends on the situation. In most cases you will need to do some async stuff inside loops though.
So my personal preference is to not use loops at all but instead go with the functional counterparts (forEach/map/reduce/filter). This way my code base stays consistent (and a sync loop is easily changed to an async one if needed).
const myArr = [1, 2, 3];
// sync loops
myArr.forEach(syncLogFunction);
console.log('after sync loop');
function syncLogFunction(entry) {
console.log('sync loop', entry);
}
// now we want to change that into an async operation:
Promise.all(myArr.map(asyncLogFunction))
.then(() => console.log('after async loop'));
function asyncLogFunction(entry) {
console.log('async loop', entry);
return new Promise(resolve => setTimeout(resolve, 100));
}
Notice how easily you can change between sync and async versions, the structure stays almost the same.
Hope this helps a bit.
Upvotes: 4