我有以下代码,每5秒调用一次web服务。这个websservice检查列表中是否有任何内容。
setTimeout(function () {
_getListItems();
}, 5000);
但是,我想在页面加载和之后每分钟检查一次,而不是每5秒检查一次。如果在列表中找到了什么,开始每5秒调用一次。有人能帮我一下吗?
尽管答案已经被接受了,但我还是要发布这个答案,因为AJAX和setInterval
的组合允许我正在开发的一个应用程序关闭负载平衡器并使所有公司的网站离线。
首先,让我们讨论一下setInterval
和setTimeout
在AJAX轮询方面的区别。
使用setInterval
的优点
- 简单的方法来执行一个函数,并触发一个AJAX请求的心跳
- 代码容易理解
- AJAX请求每X毫秒发送一次,而不必考虑请求返回所需的时间
使用setInterval
的缺点
- (这是一个大的)下一个请求在发送之前不会等待当前请求完成。当系统开始运行缓慢的服务器端时,这些AJAX请求可能会堆积起来。例如,您每5秒发送一个请求,但服务器需要10秒才能响应。在一分钟内,单个用户可以排队向服务器发送12个尚未返回给客户端的请求。现在将其乘以您拥有的并发用户数量,这个数字很快就会相加。10个用户意味着120个请求排队。100个用户=一分钟内排队的1200个请求。我工作的地方就是这么做的,我们弄坏了一个负载平衡器。他们不得不拔掉插头,因为电源按钮根本不工作。死了。在。的。水……下来。
- 如果用户的会话超时,身份验证错误更难以处理,因为如果服务器返回401 Unauthorized响应,您必须记住清除间隔
使用setTimeout
的优点
- (这是一个大的)在当前请求完成处理之前不会发送新的请求。这减轻了我上面解释的灾难。
- 身份验证错误更容易处理,因为当从服务器接收到非200 OK响应时不会发出新的请求
使用setTimeout
的缺点
- 你的代码有点复杂,因为你需要在AJAX调用成功后重新启动超时
- 请求之间的间隔是不同的,因为间隔实际上是:
timeout + AJAX request time + response processing time
,所以5000毫秒的超时可以给您大约5500毫秒的间隔,一旦您考虑到AJAX请求返回到浏览器所花费的时间,以及浏览器处理响应的时间。您可以通过跟踪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);
}
和使用函数:
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);
}
}
);
setTimeout
只在给定的时间间隔后执行一次,您的意思是setInterval
。
这些方法的返回值是标识符。使用此ID可以删除间隔。
怎么做:
-
初始检查文档准备就绪+应用
setInterval
1分钟(保存返回值在一个变量中) -
如果每分钟调用的函数列表中有项目,删除1分钟间隔,设置一个新的每5秒检查一次
.
var intervalCall = window.setInterval(function() { }, 60000);
window.clearTimeout(intervalCall);
这是你的参考:https://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval