从异步回调函数将对象推送到本地数组

时间:2014-06-21 12:17:15

标签: javascript node.js asynchronous redis

我在服务器上使用node.js,并使用redis密钥库存储有关我的字符的数据。每个连接都有自己的特征。我想把所有关于字符的数据(Person,有它的名字,年龄,专业......)放到Characters数组中,这样我就可以有选择地将它发送给连接的客户端。

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

我已经读过,这是由于异步与同步问题,所以我创建了全局变量字符。

//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 个答案:

答案 0 :(得分:1)

有不同的方式,

最简单的方法是创建一个接一个地调用异步函数,如下所示

    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);
        });
   }

答案 1 :(得分:1)

当您具有异步调用和全局变量时,常规for循环无法正常工作。这是一个可以工作的循环版本(确保安装了异步。如果没有“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]);
  }
});