Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用node.js+redis存储平均请求时间_Node.js_Redis - Fatal编程技术网

使用node.js+redis存储平均请求时间

使用node.js+redis存储平均请求时间,node.js,redis,Node.js,Redis,大家好,我有一个非常实用的redis用例问题。假设我想用以下js代码存储Redis的平均请求时间。基本上,我试图计算平均请求时间,并在每个请求条目上保存到redis[req_path,req_time] var rc=require('redis').createClient() ,rc2=require('redis').createClient() ,test_data=[ ['path/1', 100] ,['path/2', 200]

大家好,我有一个非常实用的redis用例问题。假设我想用以下js代码存储Redis的平均请求时间。基本上,我试图计算平均请求时间,并在每个请求条目上保存到redis[req_path,req_time]

var rc=require('redis').createClient()
    ,rc2=require('redis').createClient()
    ,test_data=[
        ['path/1', 100]
        ,['path/2', 200]
        ,['path/1', 50]
        ,['path/1', 70]
        ,['path/3', 400]
        ,['path/2', 150]
    ];

rc.del('reqtime');
rc.del('reqcnt');
rc.del('avgreqtime');

for(var i=0, l=test_data.length; i<l; i++) {
    var item=test_data[i], req_path=item[0], req_time=item[1];
    console.log('debug: iteration # %d, item=%j', i, item);
    rc.zincrby('reqtime', req_time, req_path );
    rc.zincrby('reqcnt', 1, req_path, function(err, c) {
        rc2.zscore('reqtime', req_path, function(err, t) {
            var avg=t/c;
            console.log('req_path='+req_path+',t='+t+',c='+c);
            console.log('debug: added member %s to sorted set "avgreqtime" with score %f', req_path, avg);
            rc2.zadd('avgreqtime', avg, req_path);
        });
    });
}
rc.quit();
rc2.quit();
redis函数中的调试行在最后一次打印,而不是在每次迭代中打印。我认为这与node.js的异步特性有关,但我不知道如何完成这项工作。作为一个实验,我还尝试用以下内容替换for循环,但没有成功:

for(var i=0, l=test_data.length; i<l; i++) {
    var item=test_data[i], req_path=item[0], req_time=item[1];
    console.log('debug: iteration # %d, item=%j', i, item);
    rc.multi()
        .zincrby('reqtime', req_time, req_path )
        .zincrby('reqcnt', 1, req_path )
        .exec( function(err, replies) {
            console.log('debug(%s): got %j', req_path, replies);
            var avg=replies[0]/replies[1];
            rc2.zadd('avgreqtime', avg, req_path);
        });
}

我使用的是Redis 2.4.5,节点Redis客户端来自

您的猜测是正确的,它与节点的异步性质有关。我将在这里尝试一个简单的示例:

for(var i = 0; i < 10; i++) {
  someAsyncFunction(i, function(err, data) {
    console.log("executed function for", i);
  });
}
现在,即使在回调中,我也将被绑定到正确的值。这不是最优的,因为我们每次都需要指定一个新函数。这样更好:

var executeTheFunction = function(i) {
  someAsyncFunction(i, function(err, data) {
    console.log("executed function for", i);
  });
};

for(var i = 0; i < 10; i++) {
  executeTheFunction(i);
}

现在,您可以使用async.queue等轻松管理此类内容。

的工作非常有魅力。感谢您指出这个有趣的模块。沉迷于这个模块,我只是在几个月前写的一篇wordpress文章中用它重写了这个示例。使用异步模块的代码要简单得多。
for(var i = 0; i < 10; i++) {
  someAsyncFunction(i, function(err, data) {
    console.log("executed function for", i);
  });
}
for(var i = 0; i < 10; i++) {
  (function(i) {
    someAsyncFunction(i, function(err, data) {
      console.log("executed function for", i);
    });
  })(i); // Execute function with parameter i immediately
}
var executeTheFunction = function(i) {
  someAsyncFunction(i, function(err, data) {
    console.log("executed function for", i);
  });
};

for(var i = 0; i < 10; i++) {
  executeTheFunction(i);
}
var calculateAverage = function(item, callback) {
    var req_path = item[0], req_time = item[1];

    rc.multi()
        .zincrby('reqtime', req_time, req_path )
        .zincrby('reqcnt', 1, req_path )
        .exec( function(err, replies) {
            if(err) return callback(err);
            console.log('debug(%s): got %j', req_path, replies);
            var avg=replies[0]/replies[1];
            rc2.zadd('avgreqtime', avg, req_path, callback);
        });
}

async.map(test_data, calculateAverage, function(err) {
    if(err)
        console.error("Error:", err);
    else
        console.log("Finished");
});