0

クライアントは、Nodejsサーバーに保存されるJSONメッセージの配列を送信します。ただし、クライアントは、メッセージごとに(一意のIDを介して)何らかの確認応答を必要とします。これは、メッセージがサーバーに適切に保存されているため、再度送信する必要がないためです。

サーバーで、JSON配列を解析してループし、各メッセージをdbに格納し、このメッセージの応答をresponsesという名前のJSON配列に格納し、最後にこの応答配列をクライアントに送信します。ただし、db操作は非同期であるため、他のすべてのコードは、db格納メソッドから返される結果の前に実行されます。私の質問は、すべてのdb操作が完了するまで、応答配列を更新し続ける方法です。

var message = require('./models/message');
var async = require('async');

var VALID_MESSAGE = 200;
var INVALID_MESSAGE = 400;
var SERVER_ERROR = 500;

function processMessage(passedMessage, callback) { 
var msg = null;
var err = null;  
var responses = [];

isValidMessage(passedMessage, function(err, result) {
if(err) {
  callback( createResponse(INVALID_MESSAGE, 0) );
}else{ 
 var keys = Object.keys(result);
for(var i=0, len = keys.length; i<len; i++) {
async.waterfall([     
  //store valid json message(s)
  function storeMessage(callback) {   
    (function(oneMessage) {
      message.processMessage(result[i], function(res) {
        callback(res, result[i].mid, callback);  
      });
    })(result[i]);
    console.log('callback returns from storeMessage()');
  },

  //create a json response to send back to client
  function createResponse(responseCode, mid, callback) {
    var status = "";
    var msg = "";

    switch(responseCode) {
    case VALID_MESSAGE: { 
      status = "pass";
      msg = "Message stored successfuly.";
      break;
    }
    case INVALID_MESSAGE: {
      status = "fail";
      msg = "Message invalid, please send again with correct data.";
      break;
    }
    case SERVER_ERROR: {
      status = "fail";
      msg = "Internal Server Error! please contact the administrator.";
      break;
    }
    default: {

      responseCode = SERVER_ERROR;
      status = "fail";
      msg = "Internal Server Error! please contact the administrator.";
      break;
    }
  }
  var response = { "mid": mid, "status": status, "message": msg, "code": responseCode};   
  callback(null, response );   
  }                     
],

function(err, result) {
  console.log('final callback in series: ', result);
  responses.push(result);          
});
}//loop ends
}//else ends
console.log('now we can send response back to app as: ', responses);  
});//isValid finishes
}
4

2 に答える 2

1

responses配列内のアイテムの数がオブジェクト内のキーの数と等しい場合にのみ配列を送信しますresult(つまり、すべてのアイテムの応答を収集しました)。配列内の各応答をプッシュした後、送信してもよいかどうかを確認できます。

于 2012-10-18T15:29:36.280 に答える
1

lanzzが言ったことを拡張するために、これはかなり一般的な解決策です(多数の「タスク」を同時に開始し、共通のコールバックを使用して、それらがすべて完了したことを判別します)。これは、userStats関数からの関数のクイックペーストです。これにより、アクティブなユーザー(DAU、WAU、およびHAU)の数が取得されます。

exports.userStats = function(app, callback)
{
    var res = {'actives': {}},
       day = 1000 * 60 * 60 * 24,
       req_model = Request.alloc(app).model,
       actives = {'DAU': day, 'MAU': day*31, 'WAU': day*7},
       countActives = function(name, time) {
           var date = new Date(new Date().getTime() - time);
           req_model.distinct('username',{'date': {$gte: date}}, function(e,c){ 
               res.actives[name] = parseInt(c ? c.length : 0, 10);
               if(Object.keys(actives).length <= Object.keys(res.actives).length)
                   callback(null, res);
           });
       };


    var keys = Object.keys(actives);
    for(var k in keys)
    {
        countActives(keys[k], actives[keys[k]]);
    }
};
于 2012-10-18T17:50:49.720 に答える