开发者

Preventing a JavaScript event listener from firing multiple times concurrently (in a Google Chrome extension)

开发者 https://www.devze.com 2023-02-09 04:55 出处:网络
I\'ve set up a Google Chrome extension that creates a context-menu of the user\'s bookmarks. As the ContextMenus API must be implemented through a background page, I added the following event listener

I've set up a Google Chrome extension that creates a context-menu of the user's bookmarks. As the ContextMenus API must be implemented through a background page, I added the following event listeners to update the context-menu if there are any changes in the user's bookmarks:

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()
});

It works, for the most part, but I've come across one bug that I cannot work out how to kill开发者_如何学JAVA. Namely, if I change multiple bookmarks concurrently (for example, by selecting multiple items in the bookmarks manager and re-arranging them), the script fires multiple times concurrently, and I end up with multiple instances of the context-menu.

Can anyone offer any suggestions on how to resolve this?


You could keep a global boolean and wrap each of your event handlers with it:

var lock = false;

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

doing the same for all your handlers. I don't know how threads are handled in chrome, so there is still a possibility of multiple threads getting through the if test before the first assignment is done, especially with multi-core processors.


I've never worked with chrome extensions before, but if you ever want to prevent things from happening side-by-side, you can usually do something like this:

  1. Have a variable called lastEventTime
  2. Every time an event happens, update the variable with the current timestamp
  3. Every time the event occurs, check to see if the current time is 2 seconds after the stored time. If not, then return;.

This should make sure that any events which happen less than two seconds after the first event will be ignored.

I'm not so sure if that solves your problem, but I hope it points you in the right direction.

0

精彩评论

暂无评论...
验证码 换一张
取 消