Chrome扩展程序背景页面和内容脚本同步

问题描述 投票:5回答:2

假设我在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);
});

是否有保证在内容脚本运行之前定义opts?例如,在启动浏览器时,后台页面将运行,并且可能会将chrome.storage.local.get的回调添加到后台页面的消息队列中。 Chrome会在注入内容脚本之前完成对该队列的处理吗?

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

javascript google-chrome-extension
2个回答
0
投票

即使在您的测试中,也不要依赖于您定义的变量。通常,由于正常的时间,你的var应该在收到消息的时候设置,但是要确保你应该在你的后台onMessage中进行检查。我已经通过在全局中记住我是否已经初始化扩展并且如果需要从onMessage这样做来解决这个问题。 xan的答案显示了在异步init完成后如何使用“return true”来处理消息。

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

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

您还可以通过伪装加载该var的后台代码中的延迟来进行实验和测试。


1
投票

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

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 + Messaging的迂回性质;您可以直接从内容脚本查询。

但是在异步处理的一般情况下,您可以推迟回复消息。你只需要从监听器返回一个真值,表明你还没有完成。

© www.soinside.com 2019 - 2024. All rights reserved.