2

I use node.js on my server and I use redis key-store for storing data about my characters. Every connection has it own character. I want to get all data about characters(Person, has its name, age, profession, ...) into Characters array, so I can then selectively send it to connected clients.

var Characters = [];
for (var ID in Connections) {
    redis_client.HGETALL(ID, function(err, result) {
        if (result) {
            Characters.push(result);
        }
    });
}
console.log(Characters);

I have read, that this is due to asynchronous vs synchronous problem, so I made global variable character.

//global variables
var character;
//function code
var Characters = [];
for (var ID in Connections) {
    redis_client.HGETALL(ID, function(err, result) {
        character = result;
    });
    if(character) {
         console.log(character); // returns correct result
         // make copy of character
        Characters.push(JSON.parse(JSON.stringify(character)));
        character = undefined;
    }
}
console.log(Characters); // array of 1 character * number of connection
                                                    //BUT I expect different character for each connection

2 Answers 2

1

there are different ways,

the easiest way would be creating calling the async function one after another, as follows

    var Characters = [];
    var objectKeys = Object.keys(Connections);
    var ID = 0; 
    if (ID < objectKeys.length) 
        doCall(objectKeys[ID]);
    else 
        console.log(Characters);
   function doCall(key) {

        redis_client.HGETALL(key, function(err, result) {
            if (result) {
                Characters.push(result);
            }
            ID++;
            if ( ID < objectKeys.length)
               doCall(objectKeys[ID]);
            else 
               console.log(Characters);
        });
   }
Sign up to request clarification or add additional context in comments.

1 Comment

Hi, could you explain me why if I replace console.log(Characters); at the 3rd row from th end with for (var ID in Connections) { Connections[ID].emit("snapshot", { MyIndex: Indices[ID], Characters: Characters });} (its socketio sending function) then whole code doesn't work(even on line where is ID++; - ID is undefined and turns into NaN. BUT: If i put this for cycle into another function and only call this function instead of console.log(Characters); code works as expected?
1

Regular for loop doesn't work correctly when you have async call and global variables. Here is a loop version that would work (make sure async is installed. if not do "npm install async"):

var async = require('async');   
var Characters = [];

async.each(Connections, function(ID, callback) {
  redis_client.HGETALL(ID, function(err, result) {
    if (result) {
        Characters.push(result);
    }
    callback(null);
  });
}, function(err) { // this function gets called when the loop is done
  console.log("finish:");
   // print out your array
  for (var i = 0, len = Characters.length; i < len; i++) {
    console.log(Characters[i]);
  }
});

3 Comments

async.each wont interate through Connection array. I have: for (ID in Connections) {console.log(ID);} and this prints keys to objects in Connections. And under this command I have async.each(Connections, ... But it wont do any operation, even when previous "for" prints some keys, it will just print "finish".
async.each() should. Did you call callback(null) as in the answer? without that, async.each() won't continue to process the next item in the array
Here is the example I ran and it works as expected, just not using HGETALL(): var async = require('async'); var Characters = []; var Connections = [1, 2, 3]; async.each(Connections, function(ID, callback) { Characters.push(ID); callback(null); }, function(err) { console.log("finish: %d", Characters.length); for (var i = 0, len = Characters.length; i < len; i++) { console.log(Characters[i]); } });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.