I'm creating a system that has 100 count down timers. Each timer makes an ajax call every second to get the endTime in the database and update the countdown time. I need to call this every second because the endTime can change. The system is currently working but its incredibly slow, and I'm curious if there is a better way than to call 100 ajax calls every second.
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 is the clean and beautiful solution for this situation as commented by @CertainPerformance
How about this workaround as suggested by @Thum Choon Tat
instead of let every one of the 100 timers make a request every 1 second to get his own
endTime(100 requests a second), make only 1 request every second and get all theendtimesof all the timers.
This is my plan
We will use localStorage to share the data between all the tabs. and save these items in it:
lastRequeted The the last time any HTML page made the request.requesterId the Id of the page that is responsible for firing the Ajax requests timerId1 , timerId2 , timerId3 , .... will hold the endTimes for every timerAny page having one or more timer from the 100 timers can request the endTimes of all the timers, and set the lastRequeted value to now, and set requesterId to it's Id
lastRequeted , if it is too old " like 4 seconds ago" , it will do the request, if it's new then it get's the data it needs from timerIdX items.requesterId no other HTMl page will do requests unless the data is too oldThis is the JS code you will use on any HTML that has a timer
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);
});
*/
}
On the server you will send the endTime for all the timers
/Timer/getAllTimers
<?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;
Now every HTML that has a timer will not fire a request, however it will check every second if the timers data is updated, then it will use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With