保持 Ajax 计时器同步

发布于 2025-01-08 02:00:11 字数 952 浏览 0 评论 0原文

我有以下 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);
    }
});
};

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

我如何才能使计时器始终在时间上减少,但仅每 30 秒左右与服务器同步一次?

精度对于该应用来说非常重要。

I have the following jQuery function that I'm using to display a timer on a page:

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);
    }
});
};

As you can see, it's actually running a script that calculates how much time is remaining until a refresh is called (with the refresh() function). I feel this is a bit intensive because it's calling every second, but I feel it's important at the same time to have synchrony in the Ajax because if the refresh() function is called too early the page stops running in sync.

How can I make it that the timer is still always decreasing in time, but only synchronises with the server every 30 seconds or so?

Precision is really important for this application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你爱我像她 2025-01-15 02:00:11

使用变量 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 处理程序中设置 Timeout,并在 error 处理程序中设置更长的超时。但这应该可以解决将更新与显示分离的问题。

不过,您肯定应该使用setInterval进行倒计时,因为setInterval尝试以确切的间隔触发,而setTimeout会造成漂移,即如果需要10ms更新DOM,那么下次调用只会在1010ms之后发生,以此类推。使用 setInterval 时,情况并非如此,因为浏览器将尽力每 1000 毫秒实际触发该函数一次。

Use a variable remainingTime to store the remaining time:

var remainingTime;

Update with ajax:

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

Continuously update:

setInterval(update, 30 * 1000);

Countdown:

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

Continuously countdown:

setInterval(countdown, 1000);

NOTE: It might be the case that you want to setTimeout inside the success handler, as you already did, and a longer timeout in the error handler. But this should do the trick for decoupling the updating from the display.

You definitely should use setInterval for the countdown though, because setInterval tries to trigger with that exact interval, whereas setTimeout will cause drift, that is, if it takes 10ms to update the DOM, the next call will only occur after 1010ms, and so on. With setInterval, this is not the case because the browser will do its best to actually trigger that function every 1000 ms.

风渺 2025-01-15 02:00:11

像这样的事情:

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);
  }
}

我已经测试过 secs modulo 30 是 10,因为这可以为您提供准确的最后 10 秒。

Something like this:

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);
  }
}

I've tested that secs modulo 30 is 10 because that gives you an accurate last 10 secs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文