2015-05-23 59 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