2016-07-24 85 views
0

因为我是AngularJS的新手,请原谅。

我有以下嵌套$ HTTP调用,

$http({ 
    method: 'GET', 
    url: host1, 
    params: { 
     'format': 'json', 
    } 
    }).then(function successCallback(response) { 
    for (var i = 0; i < response.data.length; i++) { 

     $http({ 
     method: 'GET', 
     url: response.data[i]['url'] + "packet-trace/base", 
     params: { 
      'format': 'json', 
     } 
     }).then(function successCallback(response2) { 

     //Retrieve some information from first $http call 
     var doSomething = response.data[i]['information']; 
     var doSomething2 = doSomething + response2.data['information']; 

     }, function errorCallback(response2) { 
     //Error 
     }); 
    } 

    }, function errorCallback(response) { 
     //Error 
    }); 

我需要从最初的$ HTTP调用检索数据,然后从$ HTTP检索数据,并使用这两个数据作为的一部分我的逻辑。但是,我无法从第一个$ http调用访问数据。循环计数器'i'始终等于response.data的长度。

如何访问第一个$ http调用的数据?

此外,是否有任何特定的编码约定或特定的API我可以用来顺序调用$ http?嵌套$ http调用会变得杂乱而难以维护。

谢谢。

回答

0

发生这种情况的原因是因为循环可能在AJAX调用成功之前完成迭代。在这个阶段i显然等于response.data.length

你可以捕捉值AJAX调用外,然后用它在success回调,这样你就不会依赖于回调里面i变量:

for (var i = 0; i < response.data.length; i++) { 
    // Capture the value you need here 
    var someValue = response.data[i]['information']; 

    $http({ 
     method: 'GET', 
     url: response.data[i]['url'] + "packet-trace/base", 
     params: { 
      'format': 'json', 
     } 
    }).then(function successCallback(response2) { 
     // Use the captured value from the first call here 
     var doSomething = someValue; 
     var doSomething2 = doSomething + response2.data['information']; 
    }, function errorCallback(response2) { 
     //Error 
    }); 
} 
+0

我也试过这样做。然而,同样的事情发生了,它只能够检索最后一个值。 – Ezra

+0

如果您在捕获值之后并在循环中发送AJAX请求之前放置了'console.log(someValue);',您是否会在每次迭代中看到正确的值? –

+0

是的,我可以看到各个值,但是一旦它在第二个AJAX调用中,就会消失,指向最后一个值。 – Ezra

0

那么这是因为异步特性的的JavaScript。我建议使用async作为你的用例。可能看起来有点复杂,但是一旦你理解了异步概念,使用起来很简单。这你可以做什么:

async.waterfall(
[ 
    function(callback){ 
    $http({ 
     method: 'GET', 
     url: host1, 
     params: { 
     'format': 'json', 
     } 
    }).then(function successCallback(response) { 
     callback(null, response); 
    }); 
    }, 
    function(callback, response){ 
    async.times(response.data.length, function(i,next){ 
     $http({ 
     method: 'GET', 
     url: response.data[i]['url'] + "packet-trace/base", 
     params: { 
     'format': 'json', 
     } 
     }).then(function successCallback(response2) { 

     //Retrieve some information from first $http call 
     var doSomething = response.data[i]['information']; 
     var doSomething2 = doSomething + response2.data['information']; 
     next(null,doSomething, doSomething2); 

    }, function errorCallback(err) { 
     next(err, null); 
     }); 
    }); 
    } 
], 
function(err,doSomethingArr, doSomething2Arr){ 
    // get your arrays here 

});