Firefox addon 与Firefox附加脚本和内容脚本的并发性

Firefox addon 与Firefox附加脚本和内容脚本的并发性,firefox-addon,firefox-addon-sdk,Firefox Addon,Firefox Addon Sdk,当我使用编写Firefox加载项时,我注意到加载项代码和内容脚本代码相互阻塞执行。此外,附加代码似乎甚至阻止了与其他Firefox窗口(不仅仅是选项卡)的交互 Firefox插件的并发/进程模型是什么? 是否可以同时运行附加代码和内容脚本代码,而无需协作多线程(a-la-timers)? 加载插件代码的次数是多少?每个窗口一次?每张账单一次?一次? 各国: Mozilla平台正朝着使用 显示UI、处理web内容和执行 附加组件。主加载项代码将在加载项进程中运行,并将 无法直接访问任何web内容

当我使用编写Firefox加载项时,我注意到加载项代码和内容脚本代码相互阻塞执行。此外,附加代码似乎甚至阻止了与其他Firefox窗口(不仅仅是选项卡)的交互

Firefox插件的并发/进程模型是什么?

是否可以同时运行附加代码和内容脚本代码,而无需协作多线程(a-la-timers)?

加载插件代码的次数是多少?每个窗口一次?每张账单一次?一次?

各国:

Mozilla平台正朝着使用 显示UI、处理web内容和执行 附加组件。主加载项代码将在加载项进程中运行,并将 无法直接访问任何web内容

所以我希望将来它们确实是独立的过程,不会相互干扰,但现在似乎不是这样


更新:

我曾尝试使用附加代码中的页面工作程序,但不幸的是,这仍然会阻止内容脚本(以及所有其他javascript)。我还尝试在页面工作者中使用web工作者,但在调用web工作者的postMessage函数时出现以下错误

TypeError:worker.postMessage不是函数

我还尝试在页面工作程序中创建iframe,然后在iframe中创建web工作程序,但不幸的是,我无法从页面工作程序中使用window.addEventListener。我得到以下错误:

TypeError:window.addEventMessage不是函数

最后,我尝试将脚本(通过script元素)注入到页面工作者页面中,以创建一个似乎可以工作的web工作者。很遗憾,我无法与此web worker通信,因为我只能通过document.defaultView.postMessage向其发送消息

哦,我编织的纠结的网

内容脚本->附加组件->页面工作程序->iframe->web工作程序->我的代码


我举了一个简单的例子:

package.json

{
“名称”:“测试”,
“作者”:“我”,
“版本”:“0.1”,
“全名”:“我的测试扩展名”,
“主页”:http://example.com", 
“id”:“jid1-FmgBxScAABzB2g”,
“说明”:“我的测试扩展”
}
lib/main.js

var数据=需要(“自身”)数据;
var pageMod=需要(“页面mod”);
pageMod.pageMod({
包括:[“http://*”,“https://*”],
contentScriptWhen:“开始”,
contentScriptFile:[data.url(“content.js”)],
onAttach:功能(工作程序){
worker.port.on(“消息”,函数(数据){
//用繁忙的循环模拟昂贵的操作
var start=新日期();
while(新日期()-start
data/content.js

self.port.on(“消息”,函数(响应){
警报(response.text);
});
//在附加代码中调用非常昂贵的操作
emit(“message”{time:10000});

消息系统的设计考虑了多进程环境。然而,这种环境并没有出现,看起来在不久的将来也不会发生。因此,您真正拥有的是在主线程(UI线程)的同一进程中运行的附加组件和内容脚本。这意味着一次只运行其中一个,正如您已经注意到的,没有并发性

是否可以在没有协作多线程(la定时器)的情况下同时运行附加代码和内容脚本代码

是的,您(尽管名称相似,但与
页面工作者
模块无关)。对于昂贵的操作,通常建议这样做——您不希望您的加载项在执行某些操作时停止响应消息。不幸的是,附加SDK没有正确公开web workers,因此我不得不使用建议的解决方法:

worker.port.on(“消息”),函数(消息){
//从JavaScript模块获取worker类并立即卸载它
var{Cu}=require(“chrome”);
var{Worker}=Cu.import(data.url(“dummy.jsm”);
卸载(data.url(“dummy.jsm”);
var webWorker=newworker(data.url(“expensiveOperation.js”);
webWorker.addEventListener(“消息”,函数(事件)
{
如果(event.data==“完成”)
emit(“message”{text:'done!'});
},假);
});
JavaScript模块
data/dummy.jsm
仅包含一行:

var EXPORTED_SYMBOLS=[“Worker”];
加载了多少次附加代码?每个窗口一次?每张账单一次?一次


如果您询问加载项代码:它只加载一次,只要加载项处于活动状态,它就会一直存在。至于内容脚本,每个文档都有一个单独的实例来注入脚本。

我在扩展的背景页面中发现了一个获取WebWorkers的黑客:

if(typeof(Worker) == 'undefined')
{
    var chromewin   =   win_util.getMostRecentBrowserWindow();
    var Worker      =   chromewin.Worker;
}
var worker      =   new Worker(data.url('path/to/script.js'));

通过访问主窗口的
窗口
对象,可以将
工作者
类拉入当前范围。这绕过了所有讨厌的
页面。Worker
解决方案垃圾,似乎效果相当不错。

这似乎不起作用。如果我试图在附加代码中创建web worker,那么它会显示ReferenceError:worker未定义。如果我试图在内容脚本中创建一个web worker,那么它会说ReferenceError:webWorker.addEventListener不是一个函数。@user967974:是的,在查看了一些附加SDK讨论之后,看起来web worker还没有得到真正的支持。我更新了我的答案,允许你使用它们。这似乎是可行的,但有一个奇怪的警告。我无法将postMessage中的对象传递给worker。它抛出了e