Chrome扩展后台页面和内容脚本同步

Chrome Extension Background Page and Content Script Synchronization

假设我在 Chrome 扩展程序的后台页面中有以下代码。

var opts;
chrome.storage.local.get(options, function(result) {
    opts = result[options];
});

chrome.runtime.onMessage.addListener(function(request, sender, response) {
    if (request.message === 'getOpts')
        response(opts);
});

在我的内容脚本中,我通过消息传递访问 opts

chrome.runtime.sendMessage({'message': 'getOpts'}, function(response) {
    console.log(opts);
});

是否可以保证在内容脚本 运行ning 之前定义 opts?比如浏览器启动的时候,后台页面会运行,估计会把chrome.storage.local.get的回调加入到后台页面的消息队列中。 Chrome 会在注入内容脚本之前完成该队列的处理吗?

我可以从内容脚本调用 chrome.storage.local.get,但我的问题更笼统,因为我的后台页面中有额外的异步处理。目前,我的内容脚本检查后台页面以确保一切准备就绪(使用间隔不断检查),但我不确定是否有必要进行此类检查。

您实际上可以异步回复消息。

chrome.runtime.onMessage.addListener(function(request, sender, response) {
  if (request.message === 'getOpts') {
    chrome.storage.local.get('options', function(result) {
      response(result[options]);
    });
    return true; // Indicate that response() will be called asynchronously
  }
});

chrome.storage 的情况下,这确实是愚蠢的,因为 API 专门设计用于解决在内容脚本中使用 localStorage + 消息传递的迂回性质;您可以直接从内容脚本中查询。

但一般情况下异步处理,您可以推迟回复消息。您只需要 return 来自侦听器的真实值以表明您还没有完成。

不要依赖你定义的变量,即使它在你的测试中。一般来说,由于正常的时间安排,您的 var 应该在收到消息时设置,但为了确保您应该在后台 onMessage 中进行检查。我通过在全局中记住我是否已经初始化扩展并在需要时从 onMessage 进行初始化来处理这个问题。 xan 的回答显示了如何在这种情况下使用 "return true" 在异步初始化完成后处理消息。

my chrome extension 上查看示例(搜索 bCalled

在那里你可以看到我有一个 sendResponse 方法,它负责检测回调是否已经被调用,如果没有,return true(假设异步操作正在进行并将稍后调用回调)

您还可以通过在加载该变量的后台代码中伪造延迟来进行试验和测试。