Cordova/PhoneGap:setInterval() / setTimeout() 不正常工作

4
我使用window.setInterval实现了一个简单的倒计时器。在我的桌面浏览器中它完美地运行,但在我的智能手机(Fairphone 2)的PhoneGap/Cordova应用程序中它不能正确工作。根据我的调查和网络研究,当手机进入睡眠/待机状态时,间隔/超时会被打断,这就是为什么它不能工作的原因。
令人惊讶的是,当我的手机通过USB电缆连接到电脑时,间隔/超时并没有被打断。所以很可能是一种节能功能导致了这种不良行为。
那么,我迷失了。我不知道如何实现我的简单倒计时器,当然它也应该在手机睡眠时(显示关闭)工作。是否有window.setInterval() / window.setTimeout() 的替代方法?
以下是我的简单代码(同样不起作用:window.setTimeout):
...
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/libs/jquery.js"></script>
<script>
    var min = 25;
    $(document).ready(function(){
        intervalID = window.setInterval(function () {
            --min;
            if (min > 0) {
                $("#countdown").text(min);
            }
        }, 6000);
    });
</script>
...
<p id="countdown">0m</p>

当您打开显示器时,setInterval会重新开始工作吗? - juvian
1
根据我的调查和在互联网上的研究,当手机进入睡眠/待机状态时,间隔/超时会被中断。是的,setIntervalsetTimeout只保证最小延迟。浏览器可以将其所有延迟都推迟,正如您所想的那样:“所以可能是一种节能功能导致了不良行为。”与其递减计数器,您需要知道开始时间并将当前时间与其进行比较。 - James Thorpe
@JamesThorpe 感谢确认 =) 但问题是,我想在倒计时结束时发出警报声(无需激活显示器)。 - Falco Preiseni
他们是正确的,不应该使用setTimeout/setInterval来计时。设备有一个内部时钟。在开始和当前时间之间的间隔数学应该被计算,然后你要根据时间差来做出反应,而不是假设间隔会在你认为它们应该触发时触发。浏览器是单线程的,因此其他任务可能会阻止间隔按预期触发。 - Ray Wadkins
@juvian 太难过了。谢谢你的建议 =) - Falco Preiseni
显示剩余3条评论
2个回答

7
仅使用间隔计时器更新显示。 使用系统时间决定要显示的内容。如果在显示不可见时未调用您的间隔,这没有问题。 下一次它被调用时(当显示再次打开时),它将从系统时间计算正确的经过时间,并正确显示。因此(以及其他几个原因),您永远不应假设setInterval()会保持完美的时间。 在Javascript中,它只是表示您想偶尔被调用,并且您可以设置近似时间来指定频率,但间隔可能会关闭很长一段时间。使用Date.now()获取间隔开始时间,然后每次间隔触发时获取新的系统时间并从开始时间中减去以查看经过了多少时间,然后计算要显示的内容。如果您想在25分钟计时器上显示剩余时间,可以执行以下操作:
function showTimer(selector, minutes) {
  var startTime = Date.now();
  var interval;

  function showRemaining() {
    var delta = Date.now() - startTime;     // milliseconds
    var deltaMinutes = delta / (1000 * 60);
    if (deltaMinutes < minutes) {
      // display minutes remaining
      $(selector).text(Math.round(minutes - deltaMinutes));
    } else {
      $(selector).text(0);
      clearInterval(interval);
    }
  }

  interval = setInterval(showRemaining, 15 * 1000);
  showRemaining();
}

$(document).ready(function(){
  showTimer("#countdown", 25);
});

演示: https://jsfiddle.net/jfriend00/807z860p/


如果用户更改了日期会发生什么?哈哈 ¯_(ツ)_/¯ - Saravanan Rajaraman

1

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