Javascript webservice轮询

use*_*871 2 javascript web-services polling

我有以下代码,每隔5秒调用一次web服务.此webs服务检查列表中是否有任何内容.

setTimeout(function () {
  _getListItems();
}, 5000);
Run Code Online (Sandbox Code Playgroud)

但是,我不是每隔5秒检查一次,而是想在页面加载时检查它,之后每分钟检查一次.如果列表中找到了某些内容,请每隔5秒开始调用一次.谁能帮我这个?

Gre*_*rdt 5

虽然答案已被接受,但我会发布这个,因为AJAX的组合,并setInterval允许我正在努力的应用程序取下负载均衡器并使所有公司网站脱机.

首先,让我们来讨论AJAX轮询之间setInterval和之间的差异setTimeout.

使用的优点 setInterval

  • 在心跳上执行函数和触发AJAX请求的简便方法
  • 代码很容易理解
  • 每X毫秒发送一次AJAX请求,而不必考虑请求返回的时间

使用的缺点 setInterval

  • (这是一个很大的问题)下一个请求不会等待当前请求在发送之前完成.当系统开始运行缓慢的服务器端时,这些AJAX请求可能会堆积起来.例如,您每5秒发送一次请求,但服务器需要10秒钟才能响应.在一分钟内,单个用户可以将12个请求排队到尚未返回给客户端的服务器.现在将其乘以您拥有的并发用户数,这个数字会快速增加.十个用户意味着120个请求排队.一百个用户= 1,200个请求在一分钟内排队.我在一个我们拆下负载均衡器的地方工作.由于电源按钮甚至无法正常工作,因此他们必须完全拔掉插头.死.在.的.冲淡.
  • 如果用户的会话超时,则更难以处理身份验证错误,因为如果服务器返回401 Unauthorized响应,您必须记住清除间隔

使用的优点 setTimeout

  • (这是一个很大的问题)在处理当前请求之前不会发送新请求.这减轻了我上面解释的灾难.
  • 验证错误更容易处理,因为当从服务器收到非200 OK响应时不会发出新请求

使用的缺点 setTimeout

  • 您的代码稍微复杂一些,因为您需要在成功调用AJAX后重新启动超时
  • 请求之间的时间间隔因实际间隔而异:timeout + AJAX request time + response processing time,因此,一旦考虑到AJAX请求返回浏览器所花费的时间,并且浏览器需要大约5,500毫秒的间隔,则超过5,000毫秒处理响应.您可以通过跟踪AJAX请求和处理时间并从标准超时期间减去该值来解决此问题.

基本上,使用的后果setTimeout是增加了代码复杂性,但是当服务器端的内容运行缓慢时,降低了自己系统的DDOS风险.

使用示例 setTimeout

function poll(url, method, period, beforeRequest, onSuccess, onError) {
    var xhr = new XMLHttpRequest(),
        onReadyStateChange= function() {
            if (this.readyState === 4) {
                if (this.status === 200 || this.status === 201) {
                    onSuccess(xhr);
                    setTimeout(sendRequest, period);
                }
                else if (this.status > 399) {
                    // Allow error handling code to retry the operation
                    onError(xhr, sendRequest, period);
                }
            }
        },
        sendRequest = function() {
            var data = beforeRequest(xhr) || null;
            xhr.open(method, url, true);
            xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
            xhr.send(data);
        };

    xhr.onreadystatechange = onReadyStateChange;

    setTimeout(sendRequest, period);
}
Run Code Online (Sandbox Code Playgroud)

并使用该功能:

poll("/messages", "POST", 10000,
    function beforeRequest(xhr) {
        return "?user_id=123";
    },
    function onSuccess(xhr) {
        var data = JSON.parse(xhr.responseText);
        // show messages...
    },
    function onError(xhr, sendRequest, period) {
        if (xhr.status === 401) {
            // show dialog to log in user
        }
        else {
            // retry the operation
            setTimeout(sendRequest, period + 10000);
        }
    }
);
Run Code Online (Sandbox Code Playgroud)