我在for循环中有一个for循环。第一个循环应该获得一个用户名,获得他们的评级,将它们附加到相同的列表项,然后重新开始使用下一个用户名,评级,追加等等,直到它经历了用户朋友名单。
//Get usernames
var current = Parse.User.current();
var relation = current.relation("FriendRelations");
relation.query().find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
//This shouldn't increment until the rating has been retrieved in the
// next function.
theuser = results[i].getUsername();
$('ul').prepend('<li id = "frienditems_' + i + '"><div id ="friendname">' +
results[i].getUsername() + '</div></li>');
//Get friend's rating.
//This is a query within a query.
var GameScore = Parse.Object.extend("Rating");
var query = new Parse.Query(GameScore);
query.equalTo("user", results[i].getUsername());
query.find({
success: function(result) {
//The log just outputs the last user's name each time, because I guess the
//other function already looped through completely, so it's forever set to the last one?**
console.log(theuser);
for (var y = 0; y < result.length; y++) {
var object = result[y].get("Rating");
//Logging the rating.
console.log("Rating:" + object);
$('#frienditems_' + y).append('<p class="friendrating">' + object + '</p>');
}
},
error: function(error) {}
});
}
}
});
这是我的console.log:
John
Rating:5
John
Rating:50
John
Rating:43
John
Rating:80
我希望如此:
George
Rating:5
Smith
Rating:50
Robert
Rating:43
John
Rating:80
有人可以帮忙吗?我已经查看了其他问题,但我无法弄清楚如何将它们应用到我的情况中。我希望我至少可以在第二个函数中访问第一个函数结果。
更新: Mihail的回答真的帮助了我。控制台日志现在显示以正确顺序检索的数据。但它仍未全部附加到其各自的列表项目中:
答案 0 :(得分:2)
您的问题是由对query.find()的异步调用引起的。您实际上命令浏览器从云数据库中检索您的信息,并告诉他如果成功检索任何内容后如何处理结果,同时代码继续执行(在您的情况下,for循环仍然遍历第一个集合)。 / p>
当第一个请求结束时,为了到达结尾,并且因为第二个查询的成功在第一个查询的范围内,所以变量theuser仍然被实例化并且具有可用的最后一个值。
为了防止这种情况,您可以使用带参数的函数调用来更改变量的范围。我重写了你的代码,它看起来像这样:
var current = Parse.User.current();
var relation = current.relation("FriendRelations");
var $ul = $('ul')
relation.query().find({
success:function(results){
for(var i = 0; i < results.length; i++) {
theuser = results[i].getUsername();
// you can use <<var $friendrating = $("<li id='frienditems_" + i"'/>").html(...... >>
var $friendrating = $(document.createElement("li")).attr("id", "frienditems_" + i).html('<div class="friendname">' + results[i].getUsername() + '</div>')
$ul.prepend($friendrating);
getUserRating(theuser, $friendrating);
}
}
});
function getUserRating(theUser, $node) {
//Get friend's rating.
//This is a query within a query.
var GameScore = Parse.Object.extend("Rating");
var query = new Parse.Query(GameScore);
query.equalTo("user", theUser);
query.find({
success: function(result) {
//The log just outputs the last user's name each time, because I guess the
//other function already looped through completely, so it's forever set to the last one?**
console.log(theUser);
for (var y = 0; y < result.length; y++) {
var object = result[y].get("Rating");
//Logging the rating.
console.log("Rating:" +object);
$node.append('<p class="friendrating">' + object + '</p>');
}
},
error: function(error) {
}
});
}
请注意,我没有测试过,我不是100%确定它会在第一次尝试时起作用。
答案 1 :(得分:1)
因为在这种情况下for循环完成后调用了匿名回调函数success: function(result) {}
,query.find()是一个异步调用,这意味着无论查询是什么,for循环都将独立地继续到下一次迭代.find()已经返回。
变量 theuser 始终是最后一个for循环中 theuser 的值,因为for循环能够在触发任何回调函数之前完成