使用GM_getValue GM_setValue实现锁定

时间:2010-09-17 20:48:19

标签: javascript locking greasemonkey

我有一个greasemonkey脚本,当它运行时,检查是否有可用的更新,并提示用户下载更新(如果有)。这通常可以正常工作,除非用户同时打开多个标签(例如,在启动浏览器时,或者使用“在标签中打开全部”作为书签文件夹),greasemonkey脚本将同时在每个标签中ping用户,这是为用户提供一点PITA。

我认为我在脚本实例之间唯一的通信渠道是GM_setValue / GM_getValue,它允许实例访问键/值存储。

我需要做的是提出一个锁定方案(让我们称之为GM_setLock / GM_releaseLock),所以我可以做到以下几点:

GM_setLock();
const tried_update = GM_getValue(available_version);
GM_setValue(available_version, true);
GM_releaseLock();

if (!tried_update) { prompt_user() }

如果没有锁定,我可以在不同标签中有多个实例,所有实例都会在GM_getValue(available_version)之前读取GM_setValue(available_version, true),因此用户可能会被多次ping。

问题是,如果我只能访问(我愿意假装的话)原子读取和原子写操作(并且没有原子),我不知道如何实现锁定我的头顶锁定写并返回先前的值)。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

你不能在Greasemonkey中使用那种语法,但是这样的事情应该做你想要的:

包装升级检查(或其他),如下所示:

function UpgradeCheckFunction ()
{
    //--- Put payload code here.

    alert ("I just ran an an upgrade check?!");
}


然后定义PerformOnceAcrossTabs(),如下所示:

function PerformOnceAcrossTabs (sName, oFunction)
{
    var OldValue    = GM_getValue (sName);
    if (OldValue)
    {
        //--- Optionally also do a timestamp check and clear any "locks" that are X hours old.
        return;
    }

    GM_setValue (sName, new Date().toString() );

    //--- run payload function here.
    (oFunction)();

    //--- Clear "Lock".
    GM_deleteValue (sName);
}


然后这样称呼:

PerformOnceAcrossTabs ("UpgradeCheckLock", UpgradeCheckFunction);