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
Push object into local array from asynchronous callback function
提问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]);
}
});