【问题标题】: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

【问题讨论】:

    标签: javascript node.js asynchronous redis


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 2020-06-28
    • 1970-01-01
    相关资源
    最近更新 更多