for-loop 中的变量每次迭代都不会重新分配
Variable in for-loop not being reassigned each iteration
我在 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 的回答确实帮助了我。控制台日志现在显示以正确顺序检索的数据。但它仍然没有全部附加到其各自的列表项:
因为在这种情况下for循环结束后调用匿名回调函数success: function(result) {}
,所以query.find()是一个异步调用,意味着for循环将独立继续到下一次迭代no query.find() 是否返回很重要。
变量 theuser 始终是最后一个 for 循环中 theuser 的值,因为 for 循环能够在任何触发回调函数
您的问题是由对 query.find() 的异步调用引起的。您实际上命令浏览器从云数据库中检索您的信息,并告诉他如果它成功检索到任何结果如何处理结果,同时代码继续执行(在您的情况下,for 循环仍然遍历第一个集合)。
当第一个请求结束时,for 到达末尾并且因为第二个查询的成功在第一个的范围内,变量 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% 确定它会在第一次尝试时起作用。
我在 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 的回答确实帮助了我。控制台日志现在显示以正确顺序检索的数据。但它仍然没有全部附加到其各自的列表项:
因为在这种情况下for循环结束后调用匿名回调函数success: function(result) {}
,所以query.find()是一个异步调用,意味着for循环将独立继续到下一次迭代no query.find() 是否返回很重要。
变量 theuser 始终是最后一个 for 循环中 theuser 的值,因为 for 循环能够在任何触发回调函数
您的问题是由对 query.find() 的异步调用引起的。您实际上命令浏览器从云数据库中检索您的信息,并告诉他如果它成功检索到任何结果如何处理结果,同时代码继续执行(在您的情况下,for 循环仍然遍历第一个集合)。
当第一个请求结束时,for 到达末尾并且因为第二个查询的成功在第一个的范围内,变量 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% 确定它会在第一次尝试时起作用。