Suhail Gupta
Suhail Gupta

Reputation: 23276

Should loops be avoided in Node.JS or is there a special way to handle them?

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

Answers (2)

Mankind1023
Mankind1023

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

Johannes Merz
Johannes Merz

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

Related Questions