【问题标题】:How are the web worker files loaded?Web Worker 文件是如何加载的?
【发布时间】:2020-10-14 08:29:33
【问题描述】:

我想在加载后立即向网络工作者发出一些东西。代码如下:

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-> web worker -- Hello World -> 窗口 -> console.log(ev.data)

我的问题是为什么会这样?这意味着worker.js 文件是同步加载的。对吗?

我什至尝试在 web worker 中加载其他文件:

importScripts('foo.js');
importScripts('bar.js');

即使加载这些文件也能正常工作。为什么?从底层的角度来看,Web Worker 文件是如何加载的?

【问题讨论】:

  • 消息传递是异步的。每个 JS 环境都有自己的事件队列。
  • “我的问题是为什么这行得通?” 不能正确解释问题? “如何加载 web worker 文件” Worker 也可以从同一页面上的 js 加载,而无需引用“外部”“文件”。见developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/…
  • @Bergi 我知道,但我在问关于加载工作文件的问题。是同步还是异步(new Worker("worker.js"))?好像是同步的。
  • @IonicăBizău:同步,是的,但在新的 webworker 线程中。它会立即返回一个Worker 对象。构造函数不会等待文件被加载。
  • @Bergi 好的,是否可以在文件本身加载之前从主窗口发出一些东西?如果没有,是否有 load 事件或者我可以收听并确保工作人员正在收听事件?我在使用 iframe 的 postmessage api 中遇到了类似的问题。

标签: javascript web-worker


【解决方案1】:

new Worker("worker.js") 不会“网络阻塞”调用线程(“主线程”)。 new 调用返回独立于工作人员的状态。 worker 可能尚未完成执行其脚本、加载其脚本,甚至将自身初始化为可以开始/命令加载其脚本的状态。

您的关注onmessage 设置在主线程中,独立于工作状态。这也不会阻塞。

postMessage() 调用将为工作人员排队一条消息,而无需等待其取件。此时主线程执行完毕(“跌入谷底”),其事件循环将等待事件。

worker 独立于主线程运行(嗯……这就是创建 worker 的重点)。它将首先运行其工作脚本。现在我想不出任何办法让它(暂时)产生执行,这意味着整个工作脚本需要“跌入谷底”,即在工作人员的单个事件循环获得控制权之前完成执行(再次) .

只有这样,来自主线程的消息才会在运行工作线程的事件循环时被 Javascript 接收。您的工作人员的onmessage() 函数将被调用,该函数将消息排队到主线程。甚至在 worker 的 postMessage() 完成之前,主线程可能已经接收到该消息。 (当然,如果工人空闲,这也可能发生在相反的情况下。)

worker中的中间importScripts()是同步的,阻塞worker,而不是主线程。

同步阻塞importScripts() 的替代方法是具有new Worker('worker.js', {type: 'module'}) 的模块工作者。那些将importScripts() 替换为异步import() 或同步import。到目前为止,很少有浏览器支持这一点。 Blink 可以,但是对于 Opera,我不知道如果没有 import in worker,它如何支持 module worker

(更多请尝试module worker article。)

【讨论】:

  • 您错过了 OP 混乱中最重要的部分:Worker 实例有自己的 MessagePorts,只有在启动 worker 上下文时才会纠缠在一起 (step 18 here)。在此之前,消息仍由主上下文存储。而且它还按照规范(同一部分)定义了端口未打开,也未在脚本运行之前启动事件循环。
猜你喜欢
  • 2019-05-26
  • 1970-01-01
  • 2021-08-23
  • 2012-06-27
  • 1970-01-01
  • 2021-09-27
  • 2012-12-15
  • 2017-09-06
  • 2016-02-26
相关资源
最近更新 更多