Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does XMLHttpRequest.abort prevent all Ajax calls except the first inside of a loop

I'm tinkering with achieving threading in Javascript by sending bogus Ajax requests. However I'm surprised at the behavior of my code below.

With xhr.abort() commented out, both "quarter" and "half" get interspersed to the console as I expect. But if xhr.abort() is called, only "quarter" gets sent to the console, and not "half".

Anybody with insight into how XMLHttpRequest's abort method works or situations where it would be appreciated. I've looked at documentation at https://developer.mozilla.org/en/DOM/XMLHttpRequest and it says "abort()....aborts the request if it has already been sent." The key being the *singular* request, not all others, as though XMLHttpRequest is a singleton.

function parallelize(bogusUrl, parallelFns) {
    for (var i=0, n=parallelFns.length; i<n; i++) {
        var fn = parallelFns[i]
            ,xhr;

        try {xhr = new XMLHttpRequest()}
        catch (e) {xhr = new ActiveXObject('Microsoft.XMLHTTP')}

        xhr.onreadystatechange = function() {
            if (xhr.readyState == 1) {
                fn();
                //xhr.abort();
            }
        };

        xhr.open('GET', bogusUrl);
        xhr.send(null);
    }
}

parallelize('bogusUrl', [
    function(){setInterval(function(){console.log('quarter')}, 250)},
    function(){setInterval(function(){console.log('half')}, 500)}
]);
like image 732
Dexygen Avatar asked Jan 26 '26 16:01

Dexygen


1 Answers

Blocks do not create a scope in JavaScript; only functions do. Thus, every iteration of your loop is sharing the same "xhr" variable, and its value is overwritten on each iteration.

To fix the problem, you can create a separate function to do the xhr work:

function doXHR(fn) {
    var xhr = null;

    try {xhr = new XMLHttpRequest()}
    catch (e) {xhr = new ActiveXObject('Microsoft.XMLHTTP')}

    xhr.onreadystatechange = function() {
        if (xhr.readyState == 1) {
            fn();
            //xhr.abort();
        }
    };

    xhr.open('GET', bogusUrl);
    xhr.send(null);
}

Then your loop would look like this:

for (var i=0, n=parallelFns.length; i<n; i++)
    doXHR( parallelFns[i] );
like image 194
Pointy Avatar answered Jan 29 '26 10:01

Pointy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!