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

时间:2015-10-28 08:31:51

标签: javascript google-chrome google-chrome-extension

我为Chrome编写扩展程序。我需要在后台页面处于非活动状态时运行延迟任务导致setTimeout无法在后台选项卡中工作,我尝试使用setInterval模拟setTimeout,如下面的代码(位于内容脚本中):

module.exports = function (config) {
  config.set({
    preprocessors: {
      'src/**/*.js': ['babel'],
      'test/**/*.js': ['babel']
    },
    babelPreprocessor: {
      options: {
        sourceMap: 'inline',
        retainLines: true // NEW LINE
      },
      filename: function (file) {
        return file.originalPath.replace(/\.js$/, '.es5.js');
      },
      sourceFileName: function (file) {
        return file.originalPath;
      }
    }
  });
};

当在延迟函数中调用set_interval时它不起作用:

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_timeout(function(){
  console.log('func1');
}, 2000);

set_timeout(function(){
  console.log('func2');

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

}, 3000);

为什么func1 func2 没有显示?

1 个答案:

答案 0 :(得分:1)

你显然在manifest.json中使用"persistent": false声明的event page,它在5秒不活动后被卸载。链接的文档说使用chrome.alarms API

  • 如果警报设置的时间约为5秒:

    请勿使用活动页面,切换到manifest.json中的"persistent": true

  • 如果闹钟的设置时间远大于5秒:

    的manifest.json:

    "permissions": ["alarms"],
    

    后台脚本:

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

    另请注意:

      

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

         

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