【问题标题】:Preventing a JavaScript event listener from firing multiple times concurrently (in a Google Chrome extension)防止 JavaScript 事件侦听器同时触发多次(在 Google Chrome 扩展中)
【发布时间】:2011-02-05 02:16:40
【问题描述】:

我设置了一个 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()
});

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

任何人都可以就如何解决这个问题提供任何建议吗?

【问题讨论】:

    标签: javascript google-chrome contextmenu bookmarks


    【解决方案1】:

    我以前从未使用过 chrome 扩展,但如果您想防止事情同时发生,您通常可以执行以下操作:

    1. 有一个名为“lastEventTime”的变量
    2. 每次发生事件时,使用当前时间戳更新变量
    3. 每次事件发生时,检查当前时间是否比存储时间晚 2 秒。如果不是,则“返回;”。

    这应该确保在第一个事件之后不到两秒发生的任何事件都将被忽略。

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2019-05-26
        • 1970-01-01
        • 2015-12-18
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        • 2013-09-11
        • 2020-09-06
        相关资源
        最近更新 更多