4

私は助けが必要です。

私は、node.js と socket.io を使用した非同期プログラミングに頭を悩ませようとしてきました。フロー制御が必要であることは理解していますが、それを適切に実装する方法を理解していないようです。

モジュールがセットに格納されているredisデータストアがあります。これらのモジュールの「moda」、「modb」インスタンスは「moda:instances」であり、「modb:instances」では、これらのインスタンスのプロパティは「moda:instancea」に格納されます' および 'modb:instanceb' をハッシュとして使用します。

次のjsonを取得しようとしています:

"moda": {"instancea": {"property1": "value1", "property2", "value2"}}, "modb": {"instanceb": {"property1": "value1"}}

誰かが私を正しい方向に少し押してくれませんか?

これが私の現在のコードです:

var io = require('socket.io').listen(2000);
var redis = require('redis').createClient();
var http = require('http');
var async = require('async');
var step = require('step');

io.sockets.on('connection', function (socket) {

var notifications = require('redis').createClient();
notifications.subscribe("notification");
notifications.on("message", function (channel, message) {
  socket.send(message);
  console.log(channel + ':' + message);
});

socket.on('modules', function(params, callback) {
  var response = {};
  async.series([

  function (callback) {
    console.log('1>');
    redis.smembers('modules', function (err, modules) {
      async.forEachSeries(modules, function(module, moduleCallback) {
        response[module] = {}

        redis.smembers(module + ':instances', function(err, instances) {
          async.forEachSeries(instances, function(instance, instanceCallback) {
            response[module][instance] = {}
            console.log('2>' + module + ':' +instance);
            instanceCallback();
          });
          moduleCallback();
        });
      });
      callback();
    });
  },
  function (callback) {
    console.log('3');
    callback();
  }

], function() {
  console.log(JSON.stringify(response));
});


});

});

このコードからの出力は次のとおりです。

   info  - socket.io started
   debug - client authorized
   info  - handshake authorized JMMn1I8aiOMGCMPOhC11
   debug - setting request GET /socket.io/1/websocket/JMMn1I8aiOMGCMPOhC11
   debug - set heartbeat interval for client JMMn1I8aiOMGCMPOhC11
   debug - client authorized for 
   debug - websocket writing 1::
1>
3
{"moda":{}}
2>moda:instancea
2>moda:instanceb
2>modb:instancea
4

2 に答える 2

0

この問題は、forEachSeries が 3 番目のパラメーターとして追加のコールバックを必要とする (処理全体が完了したときに呼び出される) という事実から発生します。完了したら呼び出されることを期待して、 forEachSeries の後にいくつかのコードを配置することはできません。

変更されたコードは次のとおりです。

var response = {};
async.series([

function (callback) {
  console.log('1>');
  redis.smembers('modules', function (err, modules) {
    async.forEachSeries(modules, function(module, moduleCallback) {
      response[module] = {}

      redis.smembers(module + ':instances', function(err, instances) {
        async.forEachSeries(instances, function(instance, instanceCallback) {
          response[module][instance] = {}
          console.log('2>' + module + ':' +instance);
          instanceCallback();
        }, moduleCallback );
      });
    }, callback );
  });
},
function (callback) {
  console.log('3');
  callback();
}],
function() {
   console.log(JSON.stringify(response));
});

コールバックと moduleCallback が 3 番目のパラメータとしてどのように使用されているかに注意してください。出力は次のとおりです。

1>
2>moda:instancea
2>moda:instanceb
2>modb:instancea
3
{"moda":{"instancea":{},"instanceb":{}},"modb":{"instancea":{}}}

これはあなたが期待したものだと思います。

追加の注意: forEachSeries はすべてを順番に処理し、次の操作は前の操作が完了するのを待ちます。これにより、Redis へのラウンドトリップが大量に生成されます。forEach は、パイプラインを活用するために、ここではるかに効率的である必要があります。

于 2012-09-29T08:09:50.230 に答える