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