Javascript Express.js异步问题
我对节点js的异步特性有一个问题,我对这个函数有一个简单的定义Javascript Express.js异步问题,javascript,node.js,express,Javascript,Node.js,Express,我对节点js的异步特性有一个问题,我对这个函数有一个简单的定义 var sendData = function(req, res) { var requestId = req.params.id; var dataForSend = []; database.collection('songs').find({player_id:new ObjectID(requestId)}).toArray(function(err, player) { _.eac
var sendData = function(req, res) {
var requestId = req.params.id;
var dataForSend = [];
database.collection('songs').find({player_id:new ObjectID(requestId)}).toArray(function(err, player) {
_.each(songs , function(song){
var songID = song._id;
song[song] = song;
functions.generateViewData(song,data,false, function(playerData, song) {
var dataForSong = {
// some code here
}
dataForSend.push(dataForChart);
console.log("Kako ovo ne radi leb ti jebem" + JSON.stringify(dataForChart));
});
});
res.send(dataForSend);
});
}
我的问题是,应用程序不必等待每个循环完成并填充dataForSend数组,每次Im res.send(dataForSend)空数组,如何等待此循环完成,然后将dataForSend数组发送到客户端?我建议您研究使用承诺。然后,您可以在迭代时创建一个异步承诺数组,然后在返回“发送”数据之前等待所有承诺完成 Q()是一个很好的库 像这样的事情也许
var Q = require("Q");
var sendData = function(req, res) {
var requestId = req.params.id;
var dataForSend = [];
database.collection('songs').find({player_id:new ObjectID(requestId)}).toArray(function(err, player) {
var promises = [];
_.each(songs , function(song){
var songID = song._id;
song[song] = song;
var promise = Q.fcall(function() {
functions.generateViewData(song,data,false, function(playerData, song) {
var dataForSong = {
// some code here
}
dataForSend.push(dataForChart);
console.log("Kako ovo ne radi leb ti jebem" + JSON.stringify(dataForChart));
});
});
promises.push(promise);
});
Q.all(promises).then(function() {
res.send(dataForSend);
});
});
}
将计数器初始化为您拥有的歌曲数。然后,你在循环中为每首歌减量。当您达到0时,您将发送数据
var songsRemaining = songs.length;
_.each(songs , function(song){
var songID = song._id;
song[song] = song;
functions.generateViewData(song,data,false, function(playerData, song) {
var dataForSong = {
// some code here
}
dataForSend.push(dataForChart);
songsRemaining--;
if (songsRemaining === 0) {
res.send(dataForSend);
}
});
});
您还可以反转逻辑,将计数器初始化为0,增加它,并在达到歌曲数时进行检查。这只是习惯的问题,我通常更喜欢这种情况下的倒计时逻辑。它实际上等待每个循环完成,只是你的每个循环在你所有的函数调用完成之前完成。因为functions.generateViewData是异步的,\每次迭代都在functions.generateViewData调用回调函数之前返回 我建议您使用,它的功能非常适合您的用例。你可以这样做:
var sendData = function(req, res) {
var requestId = req.params.id;
var dataForSend = [];
database.collection('songs').find({player_id:new ObjectID(requestId)}).toArray(function(err, player) {
async.each(songs,
function(song,callback){
functions.generateViewData(song,data,false, function(playerData, song) {
var dataForSong = {
// some code here
}
dataForSend.push(dataForChart);
console.log("Kako ovo ne radi leb ti jebem" + JSON.stringify(dataForChart));
//you call the callback with no parameters or null if no error occurs
callback();
});
},
function(err){
//since you never called callback with an error err will always be null and this function will be called when all your songs finished processing
res.send(dataForSend);
}
);
});
}
您还可以使用其他asyncjs函数对其进行进一步整理