2015-05-23 98 views
2

我發出兩個並行異步API調用,所以我不會鎖定瀏覽器,並且我只接收一個回調。並行異步XMLHttpRequests只回調一次

下面是代碼

/* Loop runs twice, from 0 to 1 */ 
for(var AccountIndex in walletForm.masterpublicKey){ 
    /* Bunch of code, then... */ 

    /* Construct an API call to Insight */ 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", "https://insight.bitpay.com/api/addrs/" + stringOfAddresses + "/txs?from=0&to=100", true); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
     $scope.$apply(function() { 
      txListInsight.txs[AccountIndex] = (JSON.parse(xhr.responseText)); 
      /* Set semaphore */ 
      txListInsight.txsReady[AccountIndex] = true; 
      parseTransactions(AccountIndex); 
      console.log(txList); 
     }) 
     } 
    } 
    xhr.send(); 
} 

我甚至可以看到在Chrome瀏覽器開發控制檯網絡選項卡上的兩個請求和響應是正確的。爲什麼我只得到一個回調而不是兩個?我的第二個回調是否覆蓋了第一個回調的引用?

爲什麼在互聯網上有一個名爲「AsyncXMLHttpRequest」的圖書館?我也在使用AngularJS - 我應該看看「承諾」嗎?

另一種選擇是通過將我的兩個API請求合併爲一個來完全避免這個問題,但我不確定字符限制是什麼。

+0

如果你構建XMLHttpRequest'對象的'數組會發生什麼,而不是覆蓋在每次迭代 – dm03514

+1

回調這是一種循環問題中的經典閉包。變量'xhr'被關閉,關閉需要被打破。 – slebetman

回答

1

我想明確地調用函數與當前AccountIndex應該工作,注意關閉

var xhrs = {}; 
for(var AccountIndex in walletForm.masterpublicKey){ 
    (function(AccountIndex) { 

     xhrs[AccountIndex] = new XMLHttpRequest(); 
     xhrs[AccountIndex].open("GET", "https://insight.bitpay.com/api/addrs/" + stringOfAddresses + "/txs?from=0&to=100", true); 
     xhrs[AccountIndex].onreadystatechange = function() { 
     if (xhrs[AccountIndex].readyState == 4) { 
     $scope.$apply(function() { 
      txListInsight.txs[AccountIndex] = (JSON.parse(xhrs[AccountIndex].responseText)); 
      /* Set semaphore */ 
      txListInsight.txsReady[AccountIndex] = true; 
      parseTransactions(AccountIndex); 
      console.log(txList); 
     }) 
     } 
     } 
     xhrs[AccountIndex].send(); 
    })(AccountIndex); 
} 
+0

好主意。我試了一下 - 它給出了相同的結果,只有一個回調。 – Andrew