我想循环浏览参与者的一些预测并计算一些点。要知道玩家得到多少分,我需要打电话给mongodb(使用猫鼬)。然后我想保存每个参与者的分数(稍后会这样做)
我正在使用这个异步模块:http://caolan.github.io/async/
var calculateTeamPredictionsPerRound = function (roundId) {
var roundScores = [];
predictions.find({}, {}).exec(function (err, predictions) {
console.log("predictions length: " + predictions.length)
if (err) return console.error(err);
async.each(predictions,
function (prediction) {
var teamScores = [];
console.log("team length: " + prediction.Team.length + "deelnemer: " + prediction.Participant.Name)
async.forEach(prediction.Team, function (player,callback) {
console.log("for player: " + player.PlayerName + "participant: " + prediction.Participant.Name);
teamScore.findOne({ RoundId: roundId, 'Player.Id': player.Id }, { Player: { $elemMatch: { Id: player.Id } } }).exec(function (err, player) {
console.log(player.Player[0].Name);
var playerScore = new Object;
playerScore.Name = player.Player[0].Name;
playerScore.Team = player.Player[0].Team;
playerScore.Won = setWinScore(player.Player[0]);
playerScore.Draw = setDrawScore(player.Player[0]);
playerScore.Played = setPlayedScore(player.Player[0]);
playerScore.RedCard = setRedCardScore(player.Player[0]);
playerScore.YellowCard = setYellowCardScore(player.Player[0]);
playerScore.Assist = setAssistScore(player.Player[0]);
playerScore.Goals = setGoalScore(player.Player[0]);
playerScore.OwnGoal = setOwnGoalScore(player.Player[0]);
playerScore.TotalScore = playerScore.Won + playerScore.Draw + playerScore.Played + playerScore.RedCard + playerScore.YellowCard + playerScore.Assist + playerScore.OwnGoal + playerScore.Goals;
teamScores.push(playerScore)
});
callback();
});
});
});
};
当我运行此代码时,控制台向我显示以下内容:
team length: 11 participant: test
for player: a participant: test
for player: b participant: test
for player: c participant: test
for player: d participant: test
for player: e participant: test
for player: f participant: test
for player: g participant: test
for player: h participant: test
for player: i participant: test
for player: j participant: test
for player: k participant: test
team length: 11participant: test2
for player: a participant: test2
for player: b participant: test2
for player: c participant: test2
for player: d participant: test2
for player: e participant: test2
for player: f participant: test2
for player: g participant: test2
for player: h participant: test2
for player: i participant: test2
for player: j participant: test2
for player: k participant: test
a
b
c
d
e
f
g
h
i
j
k
a
b
c
d
e
f
g
h
i
j
k
但我想要:
team length: 11participant: test
for player: a participant: test
a
for player: b participant: test
b
问题是在你的async.forEach
方法中,你使用了一个.findOne()
方法,它也是异步的。
执行顺序为:
- console.log("for player: " + player.玩家名称 + "参与者:" + prediction.Participant.Name);
- 查找一()
- 回调()
你调用异步函数的回调(),而不等待 findOne() 的回调,这是function (err, player) {...}
。
将 callback() 移到 function (err, player) {...}
内部以等待 findOne() 执行,然后再完成异步任务。
teamScore.findOne({ RoundId: roundId, 'Player.Id': player.Id }, { Player: { $elemMatch: { Id: player.Id } } }).exec(function (err, player) {
console.log(player.Player[0].Name);
var playerScore = new Object;
playerScore.Name = player.Player[0].Name;
playerScore.Team = player.Player[0].Team;
playerScore.Won = setWinScore(player.Player[0]);
playerScore.Draw = setDrawScore(player.Player[0]);
playerScore.Played = setPlayedScore(player.Player[0]);
playerScore.RedCard = setRedCardScore(player.Player[0]);
playerScore.YellowCard = setYellowCardScore(player.Player[0]);
playerScore.Assist = setAssistScore(player.Player[0]);
playerScore.Goals = setGoalScore(player.Player[0]);
playerScore.OwnGoal = setOwnGoalScore(player.Player[0]);
playerScore.TotalScore = playerScore.Won + playerScore.Draw + playerScore.Played + playerScore.RedCard + playerScore.YellowCard + playerScore.Assist + playerScore.OwnGoal + playerScore.Goals;
teamScores.push(playerScore)
callback();
});
});
此外,您可以callback(playerScore)
,而不是teamScores.push(playerScore)
,然后向 async.forEach
提供最终回调,当所有任务完成后,将使用所有 playerScore 的数组调用该回调。
如果async.forEach是这个模块,我不确定你为什么需要它,因为你的所有任务都是异步的。它不会自动使teamScore.findOne()
同步,您仍然必须使用 var done = this.async();
指定一个异步回调并在 findOne() 完成后调用它,但您也可以使用常规的 async.each() 代替。