javascript `while` 或 `for` 循环与 $http.get
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23922301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
`while` or `for` loop with $http.get
提问by Snoobie
I would like to know if it's possible to use while
or for
with a nested call to $http.get
:
我想知道是否可以使用while
或for
嵌套调用$http.get
:
This is an example:
这是一个例子:
for (var i = 0; i < $scope.comments.length; i++) {
alert($scope.comments[i].id); // = 2
$http.get('/api/logged/like/isliked?id=' + $scope.comments[i].id).success(function(data, status, header, config) {
alert('Test');
alert($scope.comments[i].id); // Not executed.
}).error(function(data){alert('The requeste isn't working');}); }
I put two alert
s to display the id of my comment I'm using to retrieve JSON. I get the id with the first alert, then 'Test' for the second, but the third alert isn't displaying. Why not?
我放了两个alert
s 来显示我用来检索 JSON 的评论的 ID。我得到第一个警报的 ID,然后是第二个警报的“测试”,但没有显示第三个警报。为什么不?
Here an example of the JSON:
这是 JSON 的示例:
{data":[
{"id":2,"is_liked":false,"nb_comments":1,"nb_likes":1,
"date_creation":"2014-05-26T17:03:54+0000"},
{"id":1,"is_liked":true,"nb_comments":0,"nb_likes":1,
"date_creation":"2014-05-26T17:00:26+0000"}
]}
回答by Marc Kline
The problem:
问题:
Don't make functions inside of a loop...
不要在循环内创建函数......
Each call of your function is actually referencing the same copy of i
in memory. A new closure is created each time the for loop runs, but each one captures the same environment. Therefore, every call to $http.get
(an asynchronous function) results in the firing of a callback referencing the same finalvalue of i
from the end of loop.
您的函数的每次调用实际上都引用了i
内存中的相同副本。每次 for 循环运行时都会创建一个新的闭包,但每个闭包都捕获相同的环境。因此,每次调用$http.get
(异步函数)都会触发一个回调,该回调引用来自循环结束的相同最终值i
。
A solution:
一个解法:
Pass i
as a parameter to a separately defined function:
传递i
作为参数来单独定义的函数:
var getIsLiked = function(i){
$http.get('isliked.json' + $scope.comments[i].id)
.success(function(data) {
console.log('Test');
console.log('i is ', i);
console.log($scope.comments[i].id);
}).error(function(data){console.log("The request isn't working");}); }
}
for (var i = 0; i < $scope.comments.length; i++) {
getIsLiked(i);
}
This can be really hard to wrap your head around, but it's worth the time to understand deeply. Not only will it help you to avoid similar problems in the future, it will also give you a better understanding of closures, an important concept in JavaScript.
这可能真的很难理解,但值得花时间深入了解。它不仅可以帮助您避免将来出现类似问题,还可以让您更好地理解闭包,这是 JavaScript 中的一个重要概念。
回答by Guillaume Besson
The third alert is inside the error
callback of your $http.get
promise. It will only be executed if the request fail. The two first alert will be executed if the request pass OR the third one will be launched if it fails.
第三个警报在error
您的$http.get
承诺的回调中。只有在请求失败时才会执行。如果请求通过,将执行第一个警报,或者如果请求失败,将启动第三个警报。