我正在尝试使用 Chrome 从 Web Worker 内部启动 Web Worker。从历史上看,这一直是 Chrome Host API 的一个问题空间,但是:
根据ChromeStatus,截至2018年10月22日
专用工作人员可以创建嵌套工作人员,但共享工作人员和服务工作人员不能。
尚不支持从共享工作线程创建嵌套专用工作线程。
嵌套共享工作线程也在规范中,但目前没有计划支持它们。
我很幸运;我正在使用一名专门的工作人员。
我找不到任何可用信息与 Chrome 桌面版本 69 中的支持声明正式矛盾(我使用的是 Chrome 72),而我的嵌套 Worker 只是坐在他的行李上,拒绝给 Janice 倒咖啡。
我有三个活动部件在起作用:一个 SlaveDriver、一个 Minion 和一个 Peon。 SlaveDriver 委托给 Minion。 Minion 委托给 Peon,Peon 完成工作,每个接收者都获得功劳。
从属驱动程序
(
function(){
var minion = new Worker('./Features/Work/Work.Minion.js');
let crackTheWhip= ()=>
{
let message = {ID: 1};
minion.postMessage(
JSON.stringify(message)
);
console.log(message.ID);
};
let take_the_credit = (message)=>
{
let work = JSON.parse(message.data);
console.log("Hot Coffee!");
console.log(JSON.stringify(work));
};
minion.onmessage = take_the_credit;
return {
GetJaniceHerCoffee: crackTheWhip
};
})();
Minion ./功能/工作/Work.Minion.js
(
function(){
var self = this;
var peon = new Worker('./Features/Work/Work.Peon.js');
let receiveWorkOrder = (message)=>
{
console.log('Delegating to a Peon');
peon.postMessage(
message.data
);
};
let take_the_credit = (message)=>
{
console.log('Taking the credit');
let work = JSON.parse(message.data);
self.postMessage(JSON.stringify(
work
));
};
peon.onmessage = take_the_credit;
self.onmessage = receiveWorkOrder;
}
)();
Peon ./功能/工作/Work.Peon.js
(
function(){
var self = this;
let receiveWorkOrder = (message)=>
{
console.log("surfing LinkedIn.");
console.log("surfing stackoverflow");
console.log("...wth is this? *sigh*");
let work_result = {Value: "Coffee"};
self.postMessage(JSON.stringify(
work_result
));
};
self.onmessage = receiveWorkOrder;
}
)();
如果我停止委派 Minion 并让他完成 Peon 的所有工作,那么一切都会顺利进行。但是,当我试图将仆从委托给苦工时,我就感到奇怪了。在 DevTools 中,当我向 Minion 发送消息时,我可以在我的线程列表中看到该 Minion 被激活。我的调试上下文跳转到工作线程,当我向 Peon 发送消息时,Peon 线程被添加到线程列表中,但所有传播似乎都停止了。控制台的日志不会发生。调试上下文不会跳转到Peon线程。我的小黄人的
take_the_credit
回调没有收到响应。
苦工只是坐在那里,不做他的工作。
为什么我的苦工拒绝给珍妮丝倒咖啡?
我的问题的答案目前可以在有关使用 Web Workers 的 MDN 文档的 Spawning Subworkers 小节中找到
如果工人愿意,他们可以产生更多工人。所谓的子工作人员必须托管在与父页面相同的源中。此外,子工作程序的 URI 是相对于父工作程序的位置而不是所属页面的位置进行解析的。这使得工作人员可以更轻松地跟踪他们的依赖项在哪里。最终,我遇到的问题根源在于,当我的 Minion Worker 尝试生成其 Peon 时,它试图引用与文档根相关的文件,而不是从 Worker 的上下文中引用,但没有输出任何内容控制台显示该文件不存在。
将这个简单的例子联系起来:
从属驱动器
<script type="application/javascript">
var slave_driver = (
function(){
let minion = new Worker('/Features/Work/Work.Minion.js');
let crackTheWhip = ()=>
{
minion.postMessage(
JSON.stringify({SERVICE: "get"})
);
};
let take_the_credit = (message)=>
{
console.log("It's about time");
alert(message.data);
};
minion.onmessage = take_the_credit;
return {
GetJaniceHerCoffee: crackTheWhip
}
}
)();
slave_driver.GetJaniceHerCoffee();
</script>
小黄人./Features/Work/Work.Minion.js
(
function(){
var self = this;
let home = location;
let peon = new Worker('/Work.Peon.js');
let receiveWorkOrder = (message)=>
{
console.log("Delegating to a Peon");
peon.postMessage(
message.data
);
}
let take_the_credit = (message)=>
{
console.log("It's about time!");
console.log("Minion Taking the Credit");
let work = JSON.parse(message.data);
self.postMessage(JSON.stringify(work));
};
peon.onmessage = take_the_credit;
self.onmessage = receiveWorkOrder;
}
)();
牡丹./Features/Work/Work.Peon.js
(
function(){
var self = this;
let receiveWorkOrder = (message)=>
{
console.log("Peon surfing stackoverflow");
console.log("Peon surfing ebay for beanie babies, cuz they're coming back, yo");
console.log("...wth is this? *sigh*");
let work_result = {Value: "Coffee"};
self.postMessage(JSON.stringify(
work_result
));
};
self.onmessage = receiveWorkOrder;
})();
请注意,当小兵生成苦工时,文件引用发生了微小的变化。
如果将“slavedriver”脚本放入 index.html 文件的正文中,并将相关模块放入其标识的位置,则当您打开索引时,您应该会收到一条显示 {"Value":"Coffee"}
的警报。