如何从Angular中的回调中访问外部范围变量?

时间:2014-02-12 01:54:29

标签: javascript angularjs callback

我在某些网页上有一个循环,我想检查它们是否可用:

var urls = ['http://www.google.com', 'http://www.facebook.com'];
for(i in urls) {
    $http({method: 'GET', url: urls[i] })
            .success(function(data, status, headers, config) {
                console.log(urls[i] + ' is available.');
            })
            .error(function(data, status, headers, config) {
                console.log(urls[i] + ' is NOT available.');
            });
}

但是urls[i]在回调函数中不可用,如何使其可访问?

2 个答案:

答案 0 :(得分:3)

仅基于该代码段,urls变量应该可以从函数中获得。 还有其他一些事情正在发生......这可能会导致问题。

由于这些方法是异步的,因此它们将在稍后的某个时间执行。那么可能正在发生的是:

var urls = ['http://www.google.com', 'http://www.facebook.com'];
for(i in urls) {
    $http({method: 'GET', url: urls[i] })
            .success(function(data, status, headers, config) {
                console.log(urls[i] + ' is available.');
            })
            .error(function(data, status, headers, config) {
                console.log(urls[i] + ' is NOT available.');
            });
}
// some time later...
urls = null;

更糟糕的是,你回调中的i不会像你期望的那样。循环将首先执行,i将最终成为(对于两个URL)最后一个被调用的URL。这是异步函数范围问题的典型案例。

当函数执行时,urls可能为null,或用于其他内容。而且,如前所述,i将不会是您所期望的。尝试将$http来电包裹在immediately-invoked function expression (IIFE)

var urls = ['http://www.google.com', 'http://www.facebook.com'];
for(i in urls) {
    (function(urls, i){
        // urls now "captured" in function-scope variable
        $http({method: 'GET', url: urls[i] })
            .success(function(data, status, headers, config) {
                console.log(urls[i] + ' is available.');
            })
            .error(function(data, status, headers, config) {
                console.log(urls[i] + ' is NOT available.');
            });
    })(urls, i);
}

我还想指出,在数组上使用for/in被认为是一个坏主意:您应该将其更改为使用带索引变量的常规for循环,或使用.forEach。以下是我将如何做到这一点(也可以轻松地消除IIFE):

var urls = ['http://www.google.com', 'http://www.facebook.com'];
urls.forEach(function(url){
    $http({method: 'GET', url: url })
        .success(function(data, status, headers, config) {
            console.log(url + ' is available.');
        })
        .error(function(data, status, headers, config) {
            console.log(url + ' is NOT available.');
        });
});

答案 1 :(得分:1)

您可以从" config.url "获取网址。在回调中。