首页 > 解决方案 > 使用 webext-redux 从后台脚本调度操作

问题描述

我正在研究 React 中的 Chrome 扩展,它在后台脚本上调用异步函数。为此,用户单击触发此功能的内容脚本上的按钮。在脚本执行时,该按钮会显示一个加载图标,并且应该在后台脚本完成后恢复。我在扩展中使用 webext-redux for Redux:https ://github.com/tshaddix/webext-redux

我没有让它正常工作,所以如果运行内容脚本的浏览器窗口保持打开状态,这里有一些伪代码可以工作

内容脚本

componentDidMount() {
   chrome.runtime.onMessage.addListener(
        (request) => {
            if(request.action === "syncComplete") {
                this.props.dispatch(syncing(false))
            }
        });
}

sync() {
  this.props.dispatch(syncing(true));
  chrome.runtime.sendMessage({action: "sync"});
}

render() {
  <a onClick={() => this.sync()}>
    {this.props.syncing ? (<span><Icon type="loading" /> Syncing...</span>) : "Force Sync" }
  </a>
}

背景脚本

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
  if(request.action === "sync") startImport();
  return true
});

async function startImport() {
     ...
  // Large async function
  // On complete or fail do:
  chrome.tabs.query({url: "https://example.com/*"}, (tabs) => {
      for (var i=0; i<tabs.length; ++i) {
          chrome.tabs.sendMessage(tabs[i].id, {action: "syncComplete"});
      }
  });
}

我面临的问题是,因为我的异步函数在后台脚本中运行(故意这样用户可以继续浏览内容脚本所在的站点),如果用户关闭内容脚本选项卡并且后台脚本完成,没有运行内容脚本来接收 Chrome 消息以调度同步操作。因此,整个扩展卡在按钮上的永久“加载”状态。

有谁知道我该如何解决这个问题,或者是否可以从后台脚本调度一个动作?

标签: javascriptreactjsgoogle-chrome-extensionreduxwebext-redux

解决方案


关闭选项卡后,内容脚本实例也随之消失,并且无法再将操作从后台页面分派到该内容脚本。(即使用户对该选项卡执行 Ctrl-Shift-T,它也会有一个新的 tabid。)

您提到您的扩展程序陷入“加载状态”。解决此问题的一种方法是localStorage在背景页面中维护一个标志,例如localStorage.hasPendingUpdate. 下次加载example.com选项卡时,向后台页面发送消息,询问是否有任何待处理的更新。如果有,后台页面将向该选项卡发送挂起的更新。


推荐阅读