javascript - 回调函数访问闭包变量?

标签 javascript angularjs closures promise

下面的代码有一个错误,但它提出了一个有趣的问题。它使用一个返回 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 循环中异步回调的经典问题。 ss1 都只声明一次。即使您在循环中声明了 var s1;,JavaScript 也没有 block 作用域,因此它是无关紧要的。

这意味着所有迭代共享相同的变量 ss1,因此当回调完成时,$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/

相关文章:

javascript - Angularjs,无法从数据库返回的 json 对象设置下拉列表

php - 类型提示闭包参数

javascript - clearInterval() 如何清除 setInterval() 中的 timerID?

javascript - 将@property设为私有(private)

javascript - jqgrid - 在 loadComplete 事件上访问 XmlHttpRequest

javascript - 在正则表达式中匹配第一组、第二组或两者

AngularJS 和 contentEditable 两种方式绑定(bind)无法按预期工作

javascript - AngularJS 按名称从变量扩展的属性过滤

java - 静态方法使 Java 成为一种伪函数式语言?

javascript - 如何根据 jquery 中的第一个日期选择器更改日期选择器日期