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

mic*_*cah 6 javascript cordova hybrid-mobile-app ionic-framework

我遇到一种情况,需要在身份验证令牌过期之前重新验证 cordova 应用程序上的令牌。为此,我想我应该在身份验证令牌到期之前设置一个超时,以重新进行身份验证。

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

  setTimeout(function() {
    .. try to reauthenticate
  }, token.expiresIn - 600*1000);
}
Run Code Online (Sandbox Code Playgroud)

我看到的问题是-

  1. 当应用程序处于睡眠状态时,超时时间已过。功能不火?

  2. 当应用程序处于睡眠状态时,超时“倒计时”(如果是这样的话)会暂停。

这些都不是好的场景。所以我的问题是,当应用程序失去焦点时超时会发生什么?我是否应该设置 10 秒的时间间隔来检查此场景的过期时间?

编辑:

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

小智 2

超时行为实际上取决于设备类型和操作系统版本。在某些情况下,一旦应用程序处于活动状态,任何“到期”的计时器都会启动。在其他系统上(我相信当前 iOS 就是这种情况),计时器在应用程序处于非活动状态时暂停,并在应用程序变为活动状态时恢复。

对于长时间运行的计时器(即您的 4 小时示例),您不能依赖它,setTimeout()因为在某些设备上它不会考虑非活动时间。您需要订阅Cordova 的恢复事件并重新计算和更新您的计时器。以下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();
        }
    });
});
Run Code Online (Sandbox Code Playgroud)