我有以下JQuery代码,每20秒进行一次ajax调用。
var uiBlocked = false;
var timerCount = 20;
window.setInterval(function() {
$.ajax({
cache: false,
type: 'HEAD',
url: '/heartbeat/',
timeout: 1000,
async: true,
success: function(data, textStatus, XMLHttpRequest) {
if (uiBlocked == true && navigator.onLine) {
uiBlocked = false;
$.unblockUI();
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
if(textStatus != 'timeout'){
if (uiBlocked == false){
uiBlocked = true;
alert(textStatus);
$.blockUI({
message: 'Lost connectivity, please reconnect your VPN.<br/>Retrying in <span id="timer">20</span> .... secs.',
css: {
border: 'none',
padding: '15px',
backgroundColor: '#000',
'-webkit-border-radius': '10px',
'- moz-border-radius': '10px',
opacity: .5,
color: '#fff'
},
onBlock: function counterFunction() {
document.getElementById("timer").innerHTML= timerCount;
timerCount--;
if(timerCount >= 0){
setTimeout(counterFunction, 1000);
}
else{
timerCount = 20;
uiBlocked = false;
}
}
});
}
}
}
})
}, 20000);
在我的错误部分中,我调用setTimeout函数来递减计数器。计数器递减并发出警报,计数器重置为20秒。但是在第二次调用时,错误回调不会被执行。这再次在第三次调用时执行。
我的计时器出错了吗?任何帮助表示赞赏。
答案 0 :(得分:0)
这听起来像定时器和间隔的古怪行为以及JS是单线程的事实。
它绝不是一个解决方案,但我建议查看John Resig的这篇伟大帖子 - 也就是jQuery先生。
我有他创作的JS Ninja Book,它有一个类似的章节,对我来说真是令人大开眼界这些操作符的行为。
答案 1 :(得分:0)
我认为您的问题可能需要setInterval
而不是递归setTimeout
。
在这里,我制作了一个jsFiddle来简化您的问题,以便更容易理解:
$(function(){
var i = 20,
interval;
$('#button').click(function(){
i = 20;
if (interval){
clearInterval(interval)
}
interval = setInterval(function(){
if (i >= 0){
$('#counter').text(i--);
} else {
clearInterval(interval)
}
}, 1000);
});
});
正如您所看到的,重置i
变量(示例中为timerCount
)以及对先前声明的clearInterval()
<setInterval()
进行操作非常重要/ p>
更新
在你的情况下
var timer;
// ....
onBlock: function counterFunction() {
timerCount = 20;
if (iterval) {
clearInterval(interval);
}
interval = setInterval(function() {
if (timerCount >= 0) {
$('#timer').text(--timerCount);
} else {
clearInterval(interval);
uiBlocked = false;
}
}, 1000);
}