最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Push object into local array from asynchronous callback function - Stack Overflow

programmeradmin0浏览0评论

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

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
Share Improve this question asked Jun 21, 2014 at 12:17 James07James07 2932 gold badges5 silver badges14 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 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);
        });
   }

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]);
  }
});
发布评论

评论列表(0)

  1. 暂无评论