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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24341529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 02:35:56  来源:igfitidea点击:

Push object into local array from asynchronous callback function

javascriptnode.jsasynchronousredis

提问by James07

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.

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

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.

我读过,这是由于异步 vs 同步问题,所以我做了全局变量字符。

//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

采纳答案by Kamrul

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

回答by Ben

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"):

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