不同步时如何同步 SetTimeout?

How to sync SetTimeout when it goes out of sync?

我有一些代码在 setTimeout 函数中指定的循环和中断几秒钟,然后一旦延迟结束,代码就会再次循环。我面临的问题是,当页面暂时失去焦点时,超时会不同步,并且代码会以“随机”间隔循环,而不是 setTimeout 延迟中指定的间隔。

当前代码供参考:

$(document).ready(function () {
    for (var key in keys) {
        element = key;
        val = keys[key];
        test(element, val);
        (function loop(element, val) {
            setTimeout(function () {
                test(element, val);
                loop(element, val);
            }, 5000);
        })(element, val);
    }
});

我搜索了一下,这个问题似乎是预料之中的,我正在尝试找到理想的解决方法,到目前为止,我已经采用了更简单的方法,即在整个页面丢失时重新加载然后重新获得焦点。它有效,但我不是很满意。

这是当前的解决方法:

$(window).blur(function(){
    $(window).focus(function(){
        location.reload();
    });
});

我还阅读了有关将 clearTimeoutfocus 一起使用以尝试重新启动或同步超时的信息,但在多次尝试中我无法正常工作。充其量它仍然会以某种形式抛出超时。

我不知道要采取哪个方向才能获得比刷新网页更合适的方法。

提前感谢您的任何建议。

我不认为这将是性能最好的解决方案。

但是你可以设置截止日期。使用 setInterval 每秒检查是否已达到截止日期。

const finish = Date.now() + 10e3;

function test(timeout) {
  console.log('Start: ', new Date().toGMTString());

  let timer = setInterval(() => {
    if (Date.now() >= timeout) {
      console.log('Finished: ', new Date(timeout).toGMTString());
      clearInterval(timer);
    }
  }, 1000);
}

test(finish);

我在另一个问题中找到了适合我的用例的合适答案。

建议很简单:当 tab/page 未获得焦点时,或者更准确地说,当它对用户隐藏时,避免 运行 依赖于定时或节流函数的代码:

if (!document.hidden){ //your animation code here }

来源:

虽然我的问题与动画无关,但有一个共性,即当页面不在视图中时会受到 setTimeout 的限制。使用这种方法,我在页面不可见时完全避免了 运行 代码,并且它避免了完全不同步,如下所示:

$(document).ready(function () {
    for (var key in keys) {
        element = key;
        val = keys[key];
        test(element, val);
        (function loop(element, val) {
            setTimeout(function () {
                if (!document.hidden) {
                    test(element, val);
                }
                loop(element, val);
            }, 5000);
        })(element, val);
    }
});