Andrew
Andrew

Reputation: 43

Parallel asyncronous XMLHttpRequests are only calling back once

I am issuing two API calls in parallel, asynchronously so I don't lock up the browser , and I am only receiving one callback.

Here is the code

/* 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();
}

I can even see the two requests in the Chrome Dev Console Network Tab and the responses are correct. Why am I only getting one callback and not two? Is my second callback overwriting the reference to the first one?

Why is there a library on the Internet called “AsyncXMLHttpRequest”? I am using AngularJS as well--shall I look into "promises"?

Another option would be to avoid the problem entirely by combining my two API requests into one, but I'm not sure what the character limit is.

Upvotes: 2

Views: 63

Answers (1)

dm03514
dm03514

Reputation: 55962

I think explicitly invoking function with the current AccountIndex should work, notice the closure

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);
}

Upvotes: 1

Related Questions