所以基本上你使用 SharedWorkers 是错误的。
来自文档:https ://developer.mozilla.org/de/docs/Web/API/SharedWorker
SharedWorker 接口代表一种特定类型的工作人员,可以从多个浏览上下文访问,例如多个窗口、iframe 甚至工作人员。
这意味着您可以跨多个窗口/选项卡/浏览上下文进行交流和计算
|-----------| |-----------|
| Window 1 | | Window 2 |
| | | |
| | | |
|-----------| |-----------|
| |
__________________
|
|-----------|
| Worker |
| |
|-----------|
在上下文中发送启动工作程序将在 SharedWorker 上打开一个端口
//============================================
//== Site Script
//============================================
var worker = new SharedWorker('something.js');
worker.port.start(); // this will trigger the on connect event on the webworker
// this will also start the worker IF this is the first call!
// recieve message from worker
worker.port.addEventListener('message', message => {
console.log(message);
});
// send a mesasge to the worker
worker.port.postMessage(['I have a nice message for all']);
//============================================
//== Shared Worker
//============================================
const allPorts = [];
onconnect = function(e) {
// the incoming port
var port = e.ports[0];
allPorts.push(port);
port.addEventListener('message', function(e) {
// get the message sent to the worker
var message = e.data[0];
// send the message to ALL connected worker ports!
allPorts.forEach(port => {
port.postMessage(message);
})
});
port.start(); // Required when using addEventListener. Otherwise called implicitly by onmessage setter.
}
您可以将 Additional Ports 发送给 worker,但 MessagePorts 是 Transferable 对象。这些需要在发送时添加到传输列表中。
const startA = document.getElementById('startA');
const startB = document.getElementById('startB');
const workerScript = 'console.log("started")';
const blob = new Blob([workerScript]);
const workerScriptURL = URL.createObjectURL(blob);
const worker = new Worker(workerScriptURL);
const messageChannel = new MessageChannel();
worker.postMessage({port: messageChannel.port2}, [messageChannel.port2]);
// ^ This is the transfer list!
如果您只想将数据传递到其他上下文,请使用 BrodcastChannel:
https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API
** 编辑 **
这是一个工作演示。尝试在一个选项卡上打开 shared.html,在另一个选项卡上打开 shared2.html。您将在第二个选项卡上看到,数字不会从 0 开始。
(shared.html)
<!DOCTYPE html><html><head></head><body>
<button onclick="init()">Initiate</button>
<script>
function init() {
w = (new SharedWorker('./shared.js')).port;
w.start();
w.postMessage(0);
w.onmessage=e=>{
console.log(e.data);
w.postMessage(e.data[0]+1);
};
}
</script></body></html>
(shared2.html)
<!DOCTYPE html><html><head></head><body>
<button onclick="init()">Initiate</button>
<script>
function init() {
w = (new SharedWorker('./shared.js')).port;
w.start();
w.onmessage=e=>{
console.log(e.data);
};
}
</script></body></html>
(shared.js)
const ports = [];
onconnect = function (ev) {
let port = ev.ports[0];
port.onmessage = (e) => {
setTimeout(()=>{
ports.forEach(p=>p.postMessage([e.data, ev.ports.length]));
},300);
}
port.start();
ports.push(port);
}