我是nodejs的新手,我不能正确理解异步功能的工作原理。我今天读了很多,但我无法解决我的问题。
我使用Sequelize.js作为ORM,我的问题是当我将查询嵌入到另一个查询的回调中时,我不能强制它仅在两个查询结束时继续。
这是我目前的代码:
io.on('connection', function (socket) {
socket.on('join', function (data) {
clients[clients.length] = new Client("Client " + clients.length, data.channel);
console.log('Client connected Channel: ' + clients[clients.length-1].channel);
var array = []
DB.Matches.findAll({attributes: ['matchId', 'teamAId', 'teamBId']}).then(function (result) {
for (var i = result.length - 1; i >= 0; i--) {
DB.Teams.findAll({where: { team_id: [result[i].teamAId,result[i].teamBId]}}).then(function (teams) {
array.push({ id: 0, name: teams[0].clubName + ' - ' + teams[1].clubName});
}).then(function () {
// Now my emit event is here but I dont want to run every time the loop run
console.log(array);
socket.emit('matches', array);
});
}
}.then(function () {
// I tried to put it here, but then I got an empty array, because the queries haven't finshed yet
}));
});
});
当调用此代码时,数组将在每个循环中发出,每个循环中都有一个元素,但这对我不利。我想在数组完全填充时调用一次emit事件。
答案 0 :(得分:5)
解决此类问题的首选方法是使用Promise.all
return { id: result[i].matchId, name: teams[0].clubName + ' - ' + teams[1].clubName};
修改强>
如果我理解你,你想写
for(var i = result.length - 1; i >= 0; i--) {
(function(i) {
promises.push(
DB.Teams.findAll({where: { team_id: [result[i].teamAId,result[i].teamBId]}}).then(function (teams) {
return { id: result[i].matchId, name: teams[0].clubName + ' - ' + teams[1].clubName};
}));
})(i);
}
但这并不奏效。这行代码将在未来的某个时刻执行, 即,在for循环结束后,到那时i为-1。 为了使它工作,你需要为循环的每次迭代提供一个新变量。 你可以这样做,例如通过将代码包装在另一个函数中来完成这个
result.forEach(function(match) {
promises.push(
DB.Teams.findAll({where: { team_id: [match.teamAId,match.teamBId]}}).then(function (teams) {
return { id: match.matchId, name: teams[0].clubName + ' - ' + teams[1].clubName};
}));
});
这样你就可以在每次迭代中使用不同的i变量(存储在内存中的不同位置)。 但在这种情况下,最好的方法是使用forEach。唯一的区别是循环会 迭代遍历数组,而不是像for循环那样向后遍历。
Invoke-RestMethod