保持Ajax计时器同步

我有以下jQuery函数,我用它来显示页面上的计时器:

function update() { $.ajax({ type: 'POST', url: 'check_time.php', data: 'checktime=true', timeout: 0, success: function(data) { $(".time_remaining").html(data); window.setTimeout(update, 1000); var time = data; if(time<=0) { $(".time_remaining").html("Reloading the page now."); refresh(); } else { $(".time_remaining").html("There are "+data+" seconds left." ); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { $("#notice_div").html('Error contacting server. Retrying in 60 seconds.'); window.setTimeout(update, 60000); } }); }; 

正如您所看到的,它实际上运行的脚本计算在调用刷新之前剩余的时间(使用refresh()函数)。 我觉得这有点密集,因为它每秒调用一次,但我觉得同时在Ajax中同步非常重要,因为如果过早调用refresh()函数,页面将停止同步运行。

如何使计时器仍然总是在时间上减少,但是每隔30秒左右只与服务器同步一次?

精度对于此应用程序非常重要。

使用变量remainingTime来存储剩余时间:

 var remainingTime; 

使用ajax更新:

 function update() { $.ajax(..., success: function(data) { remainingTime = parseInt(data, 10); }); } 

不断更新:

 setInterval(update, 30 * 1000); 

倒数:

 function countdown() { if(remainingTime-- < 0) { $(".time_remaining").text("Reloading the page now."); refresh(); } else { $(".time_remaining").text("There are " + remainingTime + " seconds left." ); } } 

连续倒计时:

 setInterval(countdown, 1000); 

注意:可能是您希望在success处理程序中设置setTimeout ,就像您已经做的那样,并且error处理程序中的超时时间更长。 但这应该可以解决更新与显示之间的问题。

肯定应该使用setInterval进行倒计时,因为setInterval尝试以精确的间隔触发,而setTimeout会导致漂移,也就是说,如果更新DOM需要10ms,下一次调用只会在1010ms后发生,依此类推。 使用setInterval ,情况并非如此,因为浏览器将尽力每1000毫秒实际触发该函数。

像这样的东西:

 function update(secs) { if (secs % 30 == 10) { $.ajax({ ... window.setTimeout("update(" + (data - 1) + ");", 1000); ... }); } else { $(".time_remaining").html("There are "+secs+" seconds left." ); window.setTimeout("update(" + (secs - 1) + ");", 1000); } } 

我已经测试了模数30秒是10,因为它可以提供准确的持续10秒。