这里是javascript的新手,所以回调在我的大脑中仍然有点不确定。
我要做的是:给出一个“菜单”,它是一个objectId数组,查询每个对应于该objectId的foodItem,得到它的投票,把它放在一个最小堆中(以确定哪些是前5项),并返回前5项。
我的堆最后是空的,因为我意识到JavaScript是异步的,当我尝试获取堆数据时,回调可能不一定完成。
如果它只是一个调用,我会嵌套回调,但由于这是一个循环,我不确定该怎么做。
function getTopFoods(menu, heap, callback) {
//go through each objectId, get its foodItem and then its votes, then heap it
console.log("got to TopFoods");
for (var i = 0; i < menu.length; i++) {
var foodID = menu[i];
var FoodItem = Parse.Object.extend("FoodItem");
var foodQuery = new Parse.Query(FoodItem);
foodQuery.equalTo("objectId", foodID);
//get corresponding foodItem
foodQuery.find({
success: function(foodResult) {
//got specific food Item
var votes = foodResult.get("votes");
console.log("votes: " + votes);
if (heap.length < 5) {
heap.queue(foodResult);
} else {
if (votes > heap.peek().get("votes")) {
heap.dequeue();
heap.queue(foodResult);
}
}
},
error: function(error) {
console.log("Food error: " + error.code + " " + error.message);
}
});
}
var topFoods = [];
for (var i = 0; i < 5; i++) {
topFoods[i] = heap.dequeue();
}
callback(topFoods);
}
答案 0 :(得分:1)
最简单的方法是使用承诺;在这个阶段,这涉及使用一个库(在ES6中适用于JavaScript)。如果你想要一个低技术的解决方案,只需计算一下:
var waitingCount = menu.length;
for (....) {
...
success: function(foodResult) {
...
if (!--waitingCount) {
callback(topFive(heap));
}
},
error: function(error) {
--waitingCount;
...
}
...
}
这只是基本的想法。如果您还在失败的响应中减少了计数器,那将是一件好事,因为这样一个单一的失败会让你不知所措。
编辑:呃,显然,支票需要转到success
的底部,而不是我之前指示的代码顶部,或者你会错过最后一个元件。我也提出错误案例。
EDIT2:正如eth3lbert所说,parse.com API也支持承诺(我不会与parse.com合作,所以......感谢您的提示)。在这种情况下,这是你做的:
var promises = [];
for (....) {
var promise = foodQuery.find({
...
});
promises.push(promise);
});
Parse.Promise.when(promises).then(function()) {
callback(topFive(heap));
}