建议使用多个 ajax 倒数计时器(每秒调用数)



我正在创建一个具有 100 个倒数计时器的系统。 每个计时器每秒进行一次 ajax 调用,以获取数据库中的 endTime 并更新倒计时时间。 我需要每秒调用它,因为末日可以改变。 该系统目前正在工作,但它非常慢,我很好奇是否有比每秒调用 100 个 ajax 调用更好的方法。

var countDownDate;
var is_locked;
var interval = 1000;
function update_timer() {
$.ajax({
type: 'POST',
url: '<?php echo base_url('/Timer/getTimer');?>',
data: {
id: <?php echo $lane->id; ?>,
},
async: false,
dataType: 'json',
success: function (response) {
var image_url = null;
$.each(response, function(k, v) {
if (k == 'end_time') {
countDownDate = new Date(v).getTime();
}
if (k == 'is_locked') {
is_locked = v;
if (is_locked == 1) {
$('.myButton').prop('disabled', true);
} else {
$('.myButton').prop('disabled', false);
}
}
})
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="demo"
document.getElementById("demo").innerHTML =  hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is finished, write some text
if (distance < 0) {
//clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
},
complete: function (data) {
// Schedule the next
setTimeout(update_timer, interval);
}
});
}
update_timer;
setTimeout(update_timer, interval);

Websockets是这种情况的干净漂亮的解决方案,正如@CertainPerformance所评论的那样

@Thum俊达建议的这种解决方法怎么样

而不是让 100 个计时器中的每一个每 1 个发出一个请求 秒获得自己的endTime(每秒 100 个请求(,每秒只发出 1 个请求,然后 获取所有计时器的所有endtimes

这是我的计划

  • 我们将使用 localStorage 在所有选项卡之间共享数据。 并将这些项目保存在其中:

    1. lastRequeted任何 HTML 页面最后一次发出请求的时间。
    2. requesterId负责触发 Ajax 请求的页面的 ID
    3. timerId1timerId2timerId3, ....将为每个计时器保留endTimes
  • 任何具有 100 个计时器中的一个或多个计时器的页面都可以请求所有计时器的endTimes,并将lastRequeted值设置为 now,并将requesterId设置为 Id

  • 我们每秒在客户端运行一个间隔来检查lastRequeted,如果它太旧"像 4 秒前",它将执行请求,如果它是新的,那么它会从timerIdX项中获取所需的数据。
  • 只有一个 HTML 页面会自行注册为requesterId除非数据太旧,否则没有其他 HTMl 页面会执行请求

这是您将在任何具有计时器的HTML上使用的JS代码

var requesterId = Math.random(); // random Id for this page
setInterval(function (){
var ts = Math.floor(Date.now() / 1000);
var lastRequested = localStorage.getItem('lastRequested');
var currentRequester = localStorage.getItem('requesterId');
if (requesterId == currentRequester ||  (ts - lastRequested > 4)){
// if I'm the current requester or the last requested time is older than 4 seconds, I will do the request
localStorage.settItem('requesterId', requesterId);
$.ajax({
type: 'POST',
url: '/Timer/getAllTimers',
dataType: 'json',
success: function(data){
localStorage.setItem('lastRequested', Math.floor(Date.now() / 1000));
for (var i =0; i < data.length; i++){
var timerId = data[i].timerId;
var timerEndTime = data[i].timerEndTime;
localStorage.setItem(timerId, timerEndTime);
}
updateTimersEndTimes();
}
} else {
// the data is updated I will get the timer endTime
updateTimersEndTimes();
}
}, 1000);
/**
* update timers endTimes from the localStorage
*/
function updateTimersEndTimes()
{
/*
// pseudo code
$("Div#timersOnPage .timer").each(function(){
var timerId = $(this).data("timerId");
var timerEndtime = LocalStorage.getItem(timerId);
$(this).data('timerEndTime', timerEndtime);
});
*/
}

在服务器上,您将发送所有计时器的结束时间

/计时器/获取所有计时器

<?php
//buid the array from your database
$timersArray = [];
for ($i = 0; $i < 100; $i++){
$timer = new stdClass();
$timer->timerId = $i;
$timer->timerEndTime = "2019-08-23 05:02:23";//changes for every timer
$timersArray[] = $timer;
}
header('Content-Type: application/json');
echo json_encode($timersArray);
exit;

现在,每个具有计时器的HTML都不会触发请求,但是它将每秒检查计时器数据是否更新,然后它将使用它。

最新更新