Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

For loop get items from redis delay

For loop get items from redis delay

Problem

I'm using Node.js w/ node_redis and am looping through an object and looking up data in Redis, then returning results.

I have it setup like this:

        for (var key in items) {
            if (items.hasOwnProperty(key)) {

                    app.client.llen(items[key].id+'_click', function(err, total) {
                        items[key].total = total;

                    });
            }
        }

       callback(items);

The problem is that it loops through, before completing the call to redis. So the Callback is called, before it's actually updated the total value. It also seems to skip some items due to the delay.

Is there a better way to handle this?

Thank you!

EDIT:

Ok, so I've updated it like this:

   getTotal(function () {
       callback(items);
   });

   getTotal = function (callback) {

       var count = 1;

       for (var key in items) {
           if (items.hasOwnProperty(key)) {
               app.client.llen(items[key].id + '_click', function (err, total) {
                   items[key].total = total;

                   if (items.length == count) {
                       callback();
                   }

                   count++;
               });
           };
       }

This seems like it would work, it triggers the callback at the appropriate time, however it seems only the last key is getting total updated.

Problem courtesy of: dzm

Solution

Your first example cannot work because a loop is synchronous while the Redis client calls are asynchronous. Your second example does not work much better because of Javascript closure management. You need a proper scope in the loop itself so the closure is handled correctly, and all the total fields updated accordingly.

Using forEach seems to be easier here:

getTotal = function (callback) {
  var count = 0;
  Object.keys( items ).forEach( function(key) {
    ++count;
    app.client.llen(items[key].id + '_click', function (err, total) {
      items[key].total = total;
      if ( --count == 0 ) {
        callback( items );
      }
    })
  })
}

getTotal( function(items) {
  console.log( items );
})
Solution courtesy of: Didier Spezia

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

For loop get items from redis delay

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×