javascript - 在扩展中,回调会累积并持续到浏览器重新启动为止

标签 javascript google-chrome-extension chrome-extension-manifest-v3

我正在将国际象棋游戏解析器移植到新的 list v3 规范。单击选定文本上的上下文菜单时,它会以可视方式将选定文本播放为 PGN国际象棋游戏符号。
问题在于,每次游戏执行时的后台脚本都会添加一个 chrome.runtime.onMessage 监听器,并且所有监听器都会持续存在,直到浏览器关闭。因此,所有监听器都会被调用,并且每次只玩第一个游戏。
有代码:

//background.js
function playBoard (info, imgPath, windowAttributes)
{
   console.log("play board with: " + info.selectionText);
   let gameObject = {
                     chessObject:
                     {
                        gametype : "PGN_OR_FEN_board",
                        content : info.selectionText,
                        imgPath : imgPath
                     }
                  };
   let windowPromise = chrome.windows.create(windowAttributes);
   windowPromise.then((value) => {
     chrome.runtime.onMessage.addListener(
         (request, sender, sendResponse) =>
         {
           console.log("backg: chrome.runtime.onMessage()> " + gameObject.chessObject.content);
           sendResponse(gameObject);
         }
       );
   });
}

上面的代码在以下上下文中调用:

//background.js

console.log("enter global>");
var idParser     = "parser parent";
var idMiniBoard  = "board mini";
var idMediuBoard = "board medium";
chrome.runtime.onInstalled.addListener(

   (details)=>
   {
      console.log("on installing");
      idParser      = chrome.contextMenus.create({"id":idParser,     "title": "Chess Parser", "contexts":["selection"]});
      idMiniBoard   = chrome.contextMenus.create({"id":idMiniBoard,  "title": "Play Small",   "contexts":["selection"], "parentId": idRoatta});
      idMediuBoard  = chrome.contextMenus.create({"id":idMediuBoard, "title": "Play Medium",  "contexts":["selection"], "parentId": idRoatta});
      chrome.contextMenus.onClicked.addListener(menuItemClick);
      console.log("on installed");
   }
)
function menuItemClick(clickData, tab)
{
   switch (clickData.menuItemId)
   {
   case idMiniBoard:
      playBoard   (clickData, "mini18", {url: "board.html", type:"popup", height : 350, width : 350});
      return;
   case idMediuBoard:
      playBoard   (clickData, "medium35", {url: "board.html", type:"popup", height: 450, width: 450});
      return;
   }
}

有弹窗启动代码

document.addEventListener('DOMContentLoaded',
   (event) =>
   {
      chrome.runtime.sendMessage({ chessObject: { gametype : "PGN_OR_FEN_board" } },
          (request) => //in fact is response, but is requested response
          {
             board_doc_main(request.chessObject);
          });

   }
);

我正在尝试应用与 Firefox 类似的方法,此处 Firefox extension, identification of context 。不知何故,对于 Firefox 来说,这是可行的。我正在尝试这样实现:从后台工作人员单击时弹出窗口打开。然后弹出窗口向后台工作人员发送消息以接收所需的上下文,包括选择游戏文本
###################
更新:
正如 @wOxxOm 的回复所建议的,这正是我现在改变的方式

function playBoard (clickData, imgPath, windowAttributes)
{
   let gameObject = {
                  chessObject:
                  {
                     gametype : "PGN_OR_FEN_board",
                     content : clickData.selectionText,
                     imgPath : imgPath
                  }
               };

   let windowPromise = chrome.windows.create(windowAttributes);
   windowPromise.then((wnd) => {
      chrome.runtime.onMessage.addListener (
         function __playBoardCallback__ (request, sender, sendResponse)
         {
            if (sender.tab?.id === wnd.tabs[0].id)
            {
               chrome.runtime.onMessage.removeListener(__playBoardCallback__);
               sendResponse(gameObject);
            }
         }
      );
   });

}

最佳答案

使用命名函数运行时立即取消注册监听器:

async function playBoard(info, imgPath, windowAttributes) {
  let gameObject = {
    // .........
  };
  const wnd = await chrome.windows.create(windowAttributes);
  const tabId = wnd.tabs[0].id;
  chrome.runtime.onMessage.addListener(function _(msg, sender, sendResponse) {
    if (sender.tab?.id === tabId) {
      chrome.runtime.onMessage.removeListener(_);
      sendResponse(gameObject);
    }
  });
}

关于javascript - 在扩展中,回调会累积并持续到浏览器重新启动为止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74933234/

相关文章:

google-chrome-extension - 安装chrome原生客户端(nacl)

javascript - 从远程 JSON 创建对象

google-chrome-extension - Chrome 扩展 list V3 远程托管代码

javascript - 用于计算特定事件的正则表达式模式

javascript - 使用 javascript 自动引用

javascript - 一个跨度内的按钮,都有一个事件。如果我单击按钮,跨度事件也会启动

google-chrome-extension - chrome扩展程序在浏览器操作弹出窗口中获得事件的选项卡ID

google-chrome-extension - chrome.scripting.executeScript 无法在具有 `tabs` 和 `<all_urls>` 主机权限的现有选项卡上运行

javascript - 单击工具栏图标时,Service Worker 不会监听操作 - Chrome 扩展 v3

javascript - 如何使用 Office.js API 在 Excel 中实现数据验证