防止JavaScript事件侦听器同时多次触发(在Google Chrome扩展程序中)

时间:2011-02-05 02:16:41

标签: javascript google-chrome contextmenu bookmarks

我已经设置了Google Chrome扩展程序,可以创建用户书签的上下文菜单。由于ContextMenus API必须通过后台页面实现,因此如果用户的书签中有任何更改,我添加了以下事件侦听器来更新上下文菜单:

chrome.bookmarks.onChildrenReordered.addListener(function () {
    chrome.contextMenus.removeAll();
    contextMenu()
});

chrome.bookmarks.onMoved.addListener(function () {
    chrome.contextMenus.removeAll();
    contextMenu()
});

chrome.bookmarks.onCreated.addListener(function () {
    chrome.contextMenus.removeAll();
    contextMenu()
});

chrome.bookmarks.onRemoved.addListener(function () {
    chrome.contextMenus.removeAll();
    contextMenu()
});

chrome.bookmarks.onImportEnded.addListener(function () {
    chrome.contextMenus.removeAll();
    contextMenu()
});

它在大多数情况下都有效,但是我遇到了一个我无法解决如何杀死的错误。也就是说,如果我同时更改多个书签(例如,通过在书签管理器中选择多个项目并重新排列它们),脚本会同时触发多次,最后我会得到上下文菜单的多个实例。

有人可以就如何解决此问题提出任何建议吗?

2 个答案:

答案 0 :(得分:0)

我之前从未使用过chrome扩展程序,但是如果你想要防止事情并发发生,你通常可以这样做:

  1. 有一个名为“lastEventTime”的变量
  2. 每次事件发生时,使用当前时间戳更新变量
  3. 每次事件发生时,检查当前时间是否为存储时间后2秒。如果没有,那么“返回;”。
  4. 这应该确保忽略在第一个事件之后不到两秒发生的任何事件。

    我不太确定这是否能解决你的问题,但我希望它能指出你正确的方向。

答案 1 :(得分:0)

您可以保留一个全局布尔值并用它包装每个事件处理程序:

var lock = false;

chrome.bookmarks.onMoved.addListener(function () {
    if(!lock) {
        lock = true;
        chrome.contextMenus.removeAll();
        contextMenu();
        lock = false;
    }
});

为所有处理程序执行相同操作。我不知道如何在chrome中处理线程,因此在第一次分配完成之前,多线程仍有可能通过if测试,尤其是对于多核处理器。