从异步回调函数将对象推送到本地数组
Posted
技术标签:
【中文标题】从异步回调函数将对象推送到本地数组【英文标题】:Push object into local array from asynchronous callback function 【发布时间】:2014-08-12 01:16:46 【问题描述】:我在我的服务器上使用 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);
我读过,这是由于异步与同步的问题,所以我做了全局变量字符。
//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
【问题讨论】:
【参考方案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);
);
【讨论】:
嗨,你能解释一下为什么如果我替换 console.log(Characters);在从第 3 行开始的第 3 行,用 for (var ID in Connections) Connections[ID].emit("snapshot", MyIndex: Indices[ID], Characters: Characters ); (它的 socketio 发送函数)然后是整个代码不起作用(即使在 ID++ 所在的行上; - ID 未定义并变成 NaN。但是:如果我将这个 for 循环放入另一个函数中并且只调用此函数而不是 console.log(Characters); 代码作为预计?【参考方案2】:当您有异步调用和全局变量时,常规 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]);
);
【讨论】:
async.each 不会通过 Connection 数组进行交互。我有: for (ID in Connections) console.log(ID); 这会打印 Connections 中对象的键。在这个命令下我有 async.each(Connections, ... 但它不会做任何操作,即使之前的“for”打印了一些键,它只会打印“finish”。 async.each() 应该。你在答案中调用了回调(null)吗?没有它, async.each() 将不会继续处理数组中的下一项 这是我运行的示例,它按预期工作,只是没有使用 HGETALL(): var async = require('async'); var 字符 = []; 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以上是关于从异步回调函数将对象推送到本地数组的主要内容,如果未能解决你的问题,请参考以下文章