下面的代码有一个错误,但它提出了一个有趣的问题。它使用一个返回 promise 的 Angular $http 服务。一旦解决,回调函数就无法访问 s1 变量。
var ids = [];
ids = ['81074'];
// show what's in
for (var s=0;s<ids.length;s++) {
var s1 = s;
$http.get('http://mydomain.com/api/catalog/product/' + ids[s]).
success(function(data) {
// console.log(s1); <--- reference error
$scope.products[s].setProductData(data);
}).error(function(err){
console.log('--------- error',err);
});
};
s1 给出 ReferenceError: s1 未在调试器中定义
有趣的是,它确实可以访问 for 循环变量 s,它始终为 1 - 正如预期的那样,因为 promise 在其递增后得到了解决(因此出现了错误 BTW)
谁能解释一下为什么?
谢谢
李尔
最佳答案
这是 for
循环中异步回调的经典问题。 s
和s1
都只声明一次。即使您在循环中声明了 var s1;
,JavaScript 也没有 block 作用域,因此它是无关紧要的。
这意味着所有迭代共享相同的变量 s
和 s1
,因此当回调完成时,$scope.products[s]
是查找 ids.length + 1
产品。
相反,做:
var ids = [];
ids = ['81074'];
function launchRequest(s) {
$http.get('http://example.com/api/catalog/product/' + ids[s]).success(function (data) {
$scope.products[s].setProductData(data);
}).error(function (err) {
console.log('--------- error', err);
});
}
// show what's in
for (var s = 0; s < ids.length; s++) {
launchRequest(s);
}
... 它在 launchRequest
中引入了一个新的函数级作用域,这意味着当回调解析时 s
仍然是函数内部的 s
.
关于javascript - 回调函数访问闭包变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16305003/