使用setInterval模拟setTimeout不适用于嵌套

Emulate setTimeout with setInterval not working for nested

本文关键字:适用于 嵌套 不适用 setTimeout setInterval 模拟 使用      更新时间:2023-09-26

我为Chrome编写扩展。当后台页面处于非活动状态时,我需要运行延迟任务。由于setTimeout在后台选项卡中不起作用,我尝试用setInterval模拟setTimeout,就像下面的代码(位于内容脚本中):

window.timings = [];
function set_timeout(func, time){
  var now = new Date() / 1;
  window.timings.push({
    func: func,
    time: time + now
  });
}
function tick(){
  var now = new Date() / 1;
  window.timings = window.timings.filter(function(delay_obj){
    if (now > delay_obj.time){
      delay_obj.func.call();
      return false;
    } else {
      return true;
    }
  });
}
$(function() {
  setInterval(tick, 1000);
  // some code
});

当延迟函数中的set_interval调用时,它不起作用

set_timeout(function(){
  console.log('func1');
}, 2000);
set_timeout(function(){
  console.log('func2');
  set_timeout(function(){
    console.log('func3');
  }, 3000);
}, 3000);

输出:

func1
func2

为什么不显示func3

您显然使用了manifest.json中用"persistent": false声明的事件页面,它在15秒的不活动后被卸载。链接的文档说明使用chrome.alarms API。

  • 对于自上次chrome事件以来延迟小于15秒的情况:

    使用setTimeoutsetInterval

  • 自上次chrome事件后延迟15-60秒:

    不要使用事件页面,在manifest.json.中切换到"persistent": true

  • 延迟60秒或以上:

    manifest.json:

      "permissions": ["alarms"],
    

    后台脚本:

      chrome.alarms.create("MyInterval1", {when: Date.now() + 1 * 60e3});
      chrome.alarms.onAlarm.addListener(function(alarm) {
          if (alarm.name == "MyInterval1") {
              console.log("Yay!");
              chrome.alarms.create("MyInterval1", {when: Date.now() + 1 * 60e3});
          }
      });
    

    另请注意:

    如果事件页面关闭,其他异步HTML5 API(如通知和地理定位)将无法完成。相反,使用等效的扩展API,如通知。

    如果您的扩展使用extension.getBackgroundPage,请切换到runtime.getBackgroundPage。较新的方法是异步的,因此如果需要,它可以在返回事件页面之前启动事件页面

请注意,在已发布的扩展中,即使指定了一个较小的值(如15秒(15*1000)),下一个报警和上次触发的报警之间的间隔也至少为1分钟。

来源:https://developer.chrome.com/docs/extensions/reference/alarms/#method-创建

为了减少用户机器上的负载,Chrome限制警报最多每1分钟一次,但可能会任意延迟数量更多。也就是说,将delayInMinutesperiodInMinutes设置为小于1将不被遵守,并将引起警告。when可以设置为"now"后不到1分钟,但不会发出警告实际上导致警报器启动至少1分钟。

加载应用程序或扩展程序后,帮助您进行调试打开后,警报器的启动频率没有限制。