javascript - 多个ajax倒计时的建议(每秒调用)
问题描述
我正在创建一个具有 100 个倒计时的系统。每个计时器每秒进行一次 ajax 调用,以获取数据库中的 endTime 并更新倒计时时间。我需要每秒调用一次,因为 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);
解决方案
正如@CertainPerformance 所评论的那样,Websockets 是针对这种情况的干净而漂亮的解决方案
@Thum Choon Tat 建议的这种解决方法怎么样
与其让 100 个计时器中的每一个每 1 秒发出一次请求以获取他自己的
endTime
请求(每秒 100 个请求),不如每秒仅发出 1 个请求并获得所有计时器endtimes
。
这是我的计划
我们将使用 localStorage 在所有选项卡之间共享数据。并将这些项目保存在其中:
lastRequeted
任何 HTML 页面最后一次发出请求。requesterId
负责触发 Ajax 请求的页面的 IDtimerId1
,timerId2
,timerId3
, .... 将为endTimes
每个计时器保留
任何具有 100 个计时器中的一个或多个计时器的页面都可以请求
endTimes
所有计时器中的一个,并将lastRequeted
值设置为现在,并将其设置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);
});
*/
}
在服务器上,您将发送所有计时器的 endTime
/定时器/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;
现在每个具有计时器的 HTML 都不会触发请求,但是如果计时器数据更新,它将每秒检查一次,然后它将使用它。
推荐阅读
- python - 你能帮我找出这段代码最坏情况下的大 O 时间复杂度吗?
- python - 如何将字符串分解为嵌套标记?
- symfony - 使用 localhost/myproject/web/app_dev.php/PATH 的 symfony 3.4 页面未完全加载
- python - 提高运行时效率的 Pythonic 解决方案
- node.js - 使用 Nodemailer 接收退回的电子邮件
- python - Python django图像上传不起作用
- php - 如何从特定于 id 的 mysql 数据库在我的 .blade 视图页面上显示照片
- javascript - 使用 R 中的 Leaflet 的 Leaftime 插件创建的时间线图中的图层控制
- python - 读取熊猫数据框中的 np 数组
- excel - Excel/VBA/Onedrive 中的方括号问题?