我放弃了。某些明智的stackoverflow僧侣可以修复我的错误吗?

代码是自我解释。客户端发送房间名称,服务器执行redis查找并将有效房间推送到阵列。添加所有房间后,该列表应发送给客户端。

问题是基于关闭,异步等。我知道问题所在,但无法解决,因为数组需要保留在函数内。整rick

码:

function roomList(socket){

  var roomlist = [], rooms = getRooms(), p = /pChannel_/;

  redis.select(7, function(err,res){

    for (var k in rooms){

      if(rooms[k] != '' && p.test(rooms[k])){

        var key = 'channel:'+rooms[k];

        redis.hgetall(key, function (err, reply) {

          if(reply){
            var c = io.sockets.manager.rooms[rooms[k]];
            roomlist.push( Array(reply['name'],c.length,reply['icon']) );
          }
          else { console.log('nothing found'); }

        });

      }

    }

    // here be dragons
    console.log(roomlist);
    socket.emit('roomList', roomlist);

  });

}

谢谢。

最佳答案

来吧OP明确表示她/她对了解事物应该如何工作很感兴趣。而且您不需要Q或async或任何其他第三方模块来实现此目的。

在初始代码中,存在两个问题:

带有Javascript的

  • ,闭包范围位于函数级别,而不是块级别。必须引入一个函数来定义适当的闭包。在这里,可以使用简单的forEach。
  • 从Redis收到回复后,最后一步(即发出)不会运行。必须在循环本身中调用它。为了实现它,需要对项目进行计数,以便内部回调可以测试该过程是否完成。

  • 所以这是另一个版本:
    function roomList(socket){
    
      var roomlist = [], rooms = getRooms(), p = /pChannel_/;
    
      redis.select(7, function(err,res){
        var count = rooms.length
        rooms.forEach( function(r) {
          if( r != '' && p.test(r) ) {
            var key = 'channel:'+r
            redis.hgetall(key, function (err, reply) {
              if(reply) {
                var c = io.sockets.manager.rooms[r];
                roomlist.push( Array(reply['name'],c.length,reply['icon']) );
              } else {
                console.log('nothing found');
              }
              if ( --count <= 0 ) {
                // here be dragons
                console.log(roomlist);
                socket.emit('roomList', roomlist);
              }
            });
          } else --count;
        });
      });
    }
    

    09-12 07:01