【问题标题】:Chrome Extension Alarms go off when Chrome is reopened after time runs out?Chrome 扩展程序警报在时间用完后重新打开 Chrome 时响起?
【发布时间】:2012-12-15 14:40:10
【问题描述】:

当使用 Google Chrome 扩展程序闹钟时,如果设置了闹钟并且 Chrome 关闭并在闹钟时间到期后重新打开,闹钟将响起。

我怎样才能阻止这种情况?

这是一个小代码示例来解释我的意思。

/* 
If we perform Browser Action to create alarm, then 
close the browser, wait about 2 minutes for the alarm to expire
and then reopen the browser, the alarm will go off and the DoSomething 
function will get called twice, once by the onStartup event and once
by the onAlarm event.
*/
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.alarms.create('myAlarm', {
        delayInMinutes : 2.0
    });
});

chrome.alarms.onAlarm.addListener(function (alarm) {
    console.log('Fired alarm!');
    if (alarm.name == 'myAlarm') {
        createListener();
    }
});

chrome.runtime.onStartup.addListener(function () {
    console.log('Extension started up...');
    DoSomething();
});

function DoSomething() {
    alert('Function executed!');
}

因此,如果您阅读我的代码示例顶部的注释,您就会看到发生了什么。

我想要的是,如果浏览器关闭,警报就会被清除,因为如果浏览器刚刚启动,我希望 DoSomething 函数仅由 onStartup 事件执行,并让警报仅执行 DoSomething 函数在浏览器启动并且我的代码创建一个新警报之后。

我不希望在浏览器关闭后留下警报,然后在重新打开浏览器时执行 onAlarm。

如何做到这一点?

【问题讨论】:

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


    【解决方案1】:

    Chrome 扩展程序无法在浏览器关闭时可靠地运行某些代码。

    与其在关机时清理,不如确保在启动时不运行旧警报。这可以通过生成唯一的(会话)标识符来实现。

    如果您使用事件页面,请将标识符存储在 chrome.storage.local 中(不要忘记在清单文件中设置 storage 权限)。否则,将其存储在全局范围内。

    // ID generation:
    chrome.runtime.onStartup.addListener(function () {
        console.log('Extension started up...');
        chrome.storage.local.set({
            alarm_suffix: Date.now()
        }, function() {
            // Initialize your extension, e.g. create browser action handler
            // and bind alarm listener
            doSomething();
        });
    });
    
    // Alarm setter:
    chrome.storage.local.get('alarm_suffix', function(items) {
        chrome.alarms.create('myAlarm' + items.alarm_suffix, {
            delayInMinutes : 2.0
        });
    });
    
    // Bind alarm listener. Note: this must happen *after* the unique ID has been set
    chrome.alarms.onAlarm.addListener(function(alarm) {
        var parsedName = alarm.name.match(/^([\S\s]*?)(\d+)$/);
        if (parsedName) {
            alarm.name = parsedName[0];
            alarm.suffix = +parsedName[1];
        }
        if (alarm.name == 'myAlarm') {
            chrome.storage.local.get('alarm_suffix', function(data) {
                if (data.alarm_suffix === alarm.suffix) {
                    doSomething();
                }
            });
        }
    });
    

    如果你不是使用事件页面,而是普通的后台页面,只需全局存储变量(优点:id读/写变为同步,需要更少的代码):

    chrome.runtime.onStartup.addListener(function () {
        window.alarm_suffix = Date.now();
    });
    chrome.alarms.create('myAlarm' + window.alarm_suffix, {
        delayInMinutes : 2.0
    });
    chrome.alarms.onAlarm.addListener(function(alarm) {
        var parsedName = alarm.name.match(/^([\S\s]*?)(\d+)$/);
        if (parsedName) {
            alarm.name = parsedName[0];
            alarm.suffix = +parsedName[1];
        }
        if (alarm.name == 'myAlarm') {
            if (alarm.suffix === window.alarm_suffix) {
                doSomething();
            }
        }
    });
    

    或者只是使用旧的setTimeout 来实现相同的目标而没有副作用。

    setTimeout(function() {
        doSomething();
    }, 2*60*1000); // 2 minutes
    

    【讨论】:

    • data.alarm_suffix === alarm.suffix 永远不会为真,因为警报的创建时间与 onStartup 事件发生的时间不同。(只有几毫秒。)
    • @user1876122 因此前面的注释“//绑定警报侦听器。注意:这必须发生在 设置唯一 ID 之后”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    相关资源
    最近更新 更多