以下是来自routes / index.js的代码的快照
exports.index = function(req, res){
var results=new Array();
for(var i=0; i<1000;i++){
//do database query or time intensive task here based on i
// add each result to the results array
}
res.render('index', { title: 'Home !' , results:results });
};
如果我运行此代码,由于javascript的异步性质,最后一行在循环完全处理之前执行。因此我的网页没有结果。我如何构建这样一种方式,一旦查询完成页面加载?
在循环内部我有数据库代码(Redis),如下所示 -
client.hgetall("game:" +i, function(err, reply) {
results.push(reply.name);
});
答案 0 :(得分:6)
exports.index = function(req, res){
var results=new Array();
async.forEach(someArray, function(item, callback){
// call this callback when any asynchronous processing is done and
// this iteration of the loop can be considered complete
callback();
// function to run after loop has completed
}, function(err) {
if ( !err) res.render('index', { title: 'Home !' , results:results });
});
};
如果循环中的某个任务是异步的,则需要向异步任务传递一个调用callback()
的回调。如果您没有要在forEach
中使用的数组,只需使用整数1-1000填充一个数组。
编辑:根据您的最新代码,只需将async
callback()
放在responses.push(reply.name)
之后。
答案 1 :(得分:3)
exports.index = function(req, res) {
var events = require("events");
var e = new events.EventEmitter();
e.expected = 1000;
e.finished = 0;
e.results = [];
e.on("finishedQuery", (function(err, r) {
this.finished += 1;
this.results.push(r && r.name);
if (this.finished === this.expected) {
res.render('index', { title: 'Home !' , results:this.results });
};
}).bind(e));
for (var i = 0; i < e.expected; i++) {
client.hgetall("game:" + i, function(err, reply) {
e.emit("finishedQuery", err, reply);
});
};
};
当然,上面的代码不能处理[1个或更多]错误。您需要添加仅对第一个错误响应(1)的逻辑或(2)如果没有错误发生。