2016-07-24 48 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 

});