假设我在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,但我的问题更通用,因为我在后台页面中有额外的异步处理。目前,我的内容脚本检查后台页面以确保一切准备就绪(使用间隔继续检查),但我不确定是否需要进行此类检查。
即使在您的测试中,也不要依赖于您定义的变量。通常,由于正常的时间,你的var应该在收到消息的时候设置,但是要确保你应该在你的后台onMessage中进行检查。我已经通过在全局中记住我是否已经初始化扩展并且如果需要从onMessage这样做来解决这个问题。 xan的答案显示了在异步init完成后如何使用“return true”来处理消息。
在my chrome extension上查看此示例(搜索bCalled
)
在那里你可以看到我有一个sendResponse方法负责检测是否已经调用了回调,如果没有,则返回true(假设异步操作正在进行中,稍后将调用回调)
您还可以通过伪装加载该var的后台代码中的延迟来进行实验和测试。
您实际上可以异步回复消息。
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的迂回性质;您可以直接从内容脚本查询。
但是在异步处理的一般情况下,您可以推迟回复消息。你只需要从监听器返回一个真值,表明你还没有完成。