【问题标题】:In JavaScript, how can I test if any AJAX call is running in the background at a given moment?在 JavaScript 中,如何测试在给定时刻是否有任何 AJAX 调用在后台运行?
【发布时间】:2014-05-15 09:23:56
【问题描述】:

我一定会使用原生 javascript(虽然如果我将 jQuery 解决方案转换为原生 javascript 也可以工作)。

另外,我没有现有 AJAX 请求的句柄,因此我无法直接访问它们。

我正在寻找类似的东西:

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

所以我可以访问这个对象并检查/操作现有的 ajax 请求。

【问题讨论】:

    标签: javascript ajax xmlhttprequest


    【解决方案1】:

    容我们说,这有点棘手。没有本地方法可以做到这一点。所以我们需要做一些修改,修改原生的XMLHttpRequest 函数。像这样的:

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

    可以用getAJAXRequests()调用。

    你可以在on jsFiddle看到它。

    【讨论】:

    • 非常好的方法!通过“重新定义” send() 方法,您在地下室工作,使您能够跟踪 any XMLHttpRequest - 无论它是由哪个框架或插件发出的。
    • 在 this.addEventListener 之后移动 oldSend.apply 行是否有意义?在添加事件侦听器之前返回响应似乎是不可能的,但也许理论上是可能的?
    【解决方案2】:

    我知道您没有特别要求 Mootools 解决方案,但我做了类似的事情,我想我会在这里分享以供其他人参考。我通过覆盖各种请求方法来实现这一点。我目前使用的是 1.5.1 版,但这个或类似的东西应该适用于其他版本。

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

    现在每次发出请求时,计数器都会增加,完成后会减少。

    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
    

    【讨论】:

    • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post
    • 我不同意我的回答离题太远了——唯一的区别是它不是原生 javascript。否则,它与上面的响应非常接近。此外,我来寻找答案并看到这篇文章的事实,我想我将来会为其他人提供一个类似但略有不同的替代方案。
    猜你喜欢
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 2017-12-26
    相关资源
    最近更新 更多