In JavaScript, how can I test if any AJAX call is running in the background at a given moment?

蓝咒 提交于 2021-02-04 13:51:26

问题


I'm bound to use native javascript (although a jQuery solution can also work if I convert it to native javascript).

Also, I have no handles to existing AJAX requests so I can't access them directly.

I am searching for something like:

var ajaxRequestsInProgress = document.getAllAjaxRunning();
ajaxRequestsInProgress[1].getStatus(); // will return the status of the request, for example

so I can access this object and check / manipulate existing ajax requests.


回答1:


This is, shall we say, a little tricky. There is no native way to do it. So we need to do a bit of hacking, modifying the native XMLHttpRequest functions. Something like this:

var getAJAXRequests = (function() {
    var oldSend = XMLHttpRequest.prototype.send,
        currentRequests = [];

    XMLHttpRequest.prototype.send = function() {
        currentRequests.push(this); // add this request to the stack
        oldSend.apply(this, arguments); // run the original function

        // add an event listener to remove the object from the array
        // when the request is complete
        this.addEventListener('readystatechange', function() {
            var idx;

            if (this.readyState === XMLHttpRequest.DONE) {
                idx = currentRequests.indexOf(this);
                if (idx > -1) {
                    currentRequests.splice(idx, 1);
                }
            }
        }, false);
    };

    return function() {
        return currentRequests;
    }
}());

It can be called with getAJAXRequests().

You can see it in action on jsFiddle.




回答2:


I know you didn't specifically ask for a Mootools solution, but I've done something similar which I thought I'd share here for others' reference. I achieve this by overriding the various request methods. I'm currently using version 1.5.1, but this or something similar should work on other versions.

(function() {
    var requestCounter = 0,
        send = Request.prototype.send,
        cancel = Request.prototype.cancel,
        onSuccess = Request.prototype.onSuccess,
        onFailure = Request.prototype.onFailure,
        timeout = Request.prototype.timeout;

    var increment = function() {
        ++requestCounter;
    };

    var decrement = function() {
        --requestCounter;

        if (requestCounter < 0) {
            requestCounter = 0;
        }
    };

    Request.implement({
        send: function() {
            increment();
            return send.apply(this, arguments);
        },
        cancel: function() {
            decrement();
            return cancel.apply(this, arguments);
        },
        onSuccess: function() {
            decrement();
            return onSuccess.apply(this, arguments);
        },
        onFailure: function() {
            decrement();
            return onFailure.apply(this, arguments);
        },
        timeout: function() {
            decrement();
            return timeout.apply(this, arguments);
        }
    });

    Request.getRunningCount = function() {
        return requestCounter;
    };
})();

Now every time a request is made, the counter will increment and when it's complete, it will decrement.

var request1 = new Request(...);
var request2 = new Request(...);

request1.send();
request2.send();
console.log(Request.getRunningCount()); // 2

request1.cancel();
console.log(Request.getRunningCount()); // 1

// request2 completes
console.log(Request.getRunningCount()); // 0


来源:https://stackoverflow.com/questions/23674175/in-javascript-how-can-i-test-if-any-ajax-call-is-running-in-the-background-at-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!