3

The following piece of code has a bug but it opened an interesting question. Its using an angular's $http service which returns a promise. Once resolved, the callback function does not have access to the s1 variable.

    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 gives ReferenceError: s1 is not defined in the debugger

And interestingly, it does have access to the for loop variable s, which is always 1 - as expected, since the promise got resolved after its incremented (hence the bug BTW)

Can someone explains why?

thanks

Lior

4

1 回答 1

9

这是for循环中异步回调的经典问题。两者ss1都只声明一次。即使您var s1;在循环中声明,JavaScript 也没有块范围,因此它是无关紧要的。

这意味着所有迭代共享相同的变量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

于 2013-04-30T16:49:59.307 回答