当窗口失去焦点时,setTimeout会发生什么?

6

我有一个情况,需要在身份验证令牌过期之前,在 Cordova 应用程序上重新验证令牌。为了做到这一点,我想在身份验证令牌即将过期之前设置一个超时时间,以便重新进行身份验证。

function authenticate() {
  var token = ... get token

  setTimeout(function() {
    .. try to reauthenticate
  }, token.expiresIn - 600*1000);
}

我看到的问题是-

  1. 应用程序睡眠时超时时间已过。 功能不会触发?

  2. 如果应用程序正在休眠,则超时“倒计时”(如果是这样工作)将暂停。

这两种情况都不是好的场景。因此,我的问题是,在应用程序失去焦点时超时会发生什么?对于这种情况,我是否应该使用10秒间隔来检查过期?

编辑:

假设令牌有效期为4小时。 如果用户使用应用程序1小时,最小化它2小时并返回,函数将在1小时或3小时后调用吗?这就是间隔的目的,以便我可以相对快速地检查情况。


你在间隔方面也会遇到同样的问题。为什么不延长令牌的生命周期——假设你控制它呢? - Darren Wainwright
我无法控制那个。 - micah
JavaScript 运行在与浏览器 UI 相同的线程上,因此 setTimeout 或 setInterval 不保证在指定时间后立即执行。Web Workers 可能是解决这个问题的一种方法。https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers 在这里使用了一个示例 https://dev59.com/83zaa4cB1Zd3GeqPWvfj - Oluwakayode Dagbo
1个回答

2
超时行为实际上取决于设备类型和操作系统版本。在某些设备上,任何“到期”的定时器都会在应用程序变为活动状态时立即触发。而在其他设备上(我相信当前的iOS是这种情况),定时器在您的应用程序处于非活动状态时被暂停,并在其重新变为活动状态时恢复。
对于长时间运行的定时器(例如您提到的4小时),您不能依赖setTimeout(),因为在某些设备上它不会考虑非活动时间。您需要订阅Cordova的resume事件并重新计算和更新您的定时器。下面的setLongTimeout()函数应该在Cordoval中按预期工作。它未经测试,如果您需要多个长时间超时,则需要进行扩展。
var longTimeoutId, longTimeoutDate, longTimeoutCallback;

// Use instead of `setTimeout()` for a long timeout in Cordova
function setLongTimeout(callback, delay) {
    if (longTimeoutId) {
        clearTimeout(longTimeoutId);
    }

    longTimeoutCallback = callback;
    longTimeoutDate = Date.now() + delay;

    longTimeoutId = setTimeout(function() {
        longTimeoutId = null;
        callback();
    }, delay);
}

document.addEventListener("deviceready", function() {
    document.addEventListener("resume", function() {
        if (longTimeoutId) {
            setLongTimeout(callback, longTimeoutDate - Date.now();
        }
    });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接