我想在加载后立即向web-worker发出一些东西。代码如下:
var w = new Worker("worker.js");
w.onmessage = function (ev) {
console.log(ev.data);
};
w.postMessage("Hello World");
在worker.js
我有:
this.onmessage = function (ev) {
self.postMessage(ev.data);
}
所以,事件流程是这样的:
窗口 -
Hello World
- >网络工作者 -Hello World
- >窗口 - >console.log(ev.data)
我的问题是为什么这有效?这意味着worker.js
文件已同步加载。这是对的吗?
我甚至尝试在网络工作者中加载其他文件:
importScripts('foo.js');
importScripts('bar.js');
即使加载这些文件也能正常工作。为什么?从低级别角度来看,如何加载Web worker文件?
答案 0 :(得分:0)
new Worker("worker.js")
不会“网络阻止”调用线程(“主线程”)。 new
调用返回独立于工作程序状态的状态。工作人员可能还没有完成执行脚本,加载脚本甚至将自己初始化为可以开始/命令加载脚本的状态。
您跟随的onmessage
是在独立于工作程序状态的主线程中设置的。那也不会阻止。
postMessage()
呼叫将为工作人员排队一条消息,而无需等待其接听。至此,主线程已完成执行(“穿到底”),其事件循环将等待事件。
worker独立于主线程运行(嗯...这就是创建worker的全部要点)。它将首先通过其工作脚本运行。现在,我想不出任何办法来(临时)产生执行,这意味着整个工作程序脚本需要“跌入谷底”,即在对工作程序的单个事件循环进行控制之前(再次)完成执行。
只有这样,当Javascript运行辅助线程的事件循环时,主线程的消息才会被Javascript接收。您的工作人员的onmessage()
函数将被调用,该函数将一条消息排队到主线程。该消息可能已经在工作人员的postMessage()
完成之前被主线程接收了。 (当然,如果工人空闲,那也可能发生在相反的方向。)
工作程序中的中间importScripts()
是同步的,并阻塞工作程序,而不是主线程。
使用importScripts()
的模块工作程序是同步阻止new Worker('worker.js', {type: 'module'})
的替代方法。那些将importScripts()
替换为异步import()
或同步import
。到目前为止,几乎没有浏览器支持该功能。眨眼可以,但是对于Opera我不知道如何在没有module worker的情况下支持import in worker。
(有关更多信息,请尝试此module worker article。)