node_redis:在forEach中使用client.multi

我有下面的代码,应该检索设备列表,并获得他们每个人的状态和标签:

app.get('/test', function(req, res){ db.smembers("devices", function(err1, devices){ var jsonObj = {}; if(!err1) { var i = 0; devices.forEach(function(id){ db.multi([ ["get", id + ":label"], ["get", id + ":status"], ]).exec(function (err, replies) { jsonObj[id] = {"label":replies[0], "status":replies[1]}; console.log(jsonObj); // stuff is added on each loop }); i = i + 1; if(i == devices.length){ console.log(jsonObj); // jsonObj is {} h.respond(res, jsonObj); } }); } else { h.respond(res, { "error" : err1 }); } }); }); 

设备是一个ID列表。 对于每个ID,有2个键:“ID:状态”,“ID:标签”

h.respond是发送http响应的辅助方法。

我可以看到新的数据被添加到每个循环的jsonObj,但是当所有的循环完成时,它是空的。

代码正在asynchronous运行,并且在任何Redis调用实际完成之前计数到devices.length(在继续之前,不等待multi的callback返回)。 将支票移入callback将防止这种情况。

 app.get('/test', function(req, res){ db.smembers("devices", function(err1, devices){ var jsonObj = {}; if(!err1) { var i = 0; devices.forEach(function(id){ db.multi([ ["get", id + ":label"], ["get", id + ":status"], ]).exec(function (err, replies) { jsonObj[id] = {"label":replies[0], "status":replies[1]}; console.log(jsonObj); // stuff is added on each loop i = i + 1; if(i == devices.length){ console.log(jsonObj); // jsonObj is {} h.respond(res, jsonObj); } }); }); } else { h.respond(res, { "error" : err1 }); } }); }); 

将代码移入单独的函数可能会更有意义,但希望您能明白这一点。 像async这样的asynchronous库提供了辅助方法,使得像这样做并行asynchronous循环变得更容易。