为什么 WebWorker 无法访问 DOM?
Why can't WebWorkers have access to the DOM?
我们都知道我们可以启动一些网络工作者,给他们一些平凡的任务来完成并在某个时候得到响应,在这个阶段我们通常会解析数据并以某种方式将其呈现给用户。
嗯...谁能提供一个相对深入的解释来说明为什么 Web Worker 无法访问 DOM?鉴于经过深思熟虑的 OO 设计方法,我只是不明白为什么他们不应该这样做?
已编辑:
我知道这是不可能的,也没有实际的答案,但我觉得我需要更深入的解释。如果您觉得与社区无关,请随时关闭问题。
浏览器中 Javascript 的整个世界最初设计时进行了极大的简化 - 单线程(在有 webWorkers 之前)。这个单一的假设使浏览器的编码变得更加简单,因为永远不会有线程争用,也永远不会有 activity 的两个线程试图同时修改相同的对象或属性。这使得在浏览器中编写 Javascript 和在浏览器中实现 Javascript 变得更加简单。
然后,需要能够做一些更长的 运行 "background" 类型的事情,而不会阻塞主线程。好吧,将它放入现有浏览器中的唯一实用方法是确保 Javascript 的 "new" 线程能够永远不要搞乱现有的主线程。
因此,它的实现方式是它可以与主线程或主线程可以修改的任何对象(例如整个 DOM 和几乎所有主机对象)进行通信的唯一方式) 是通过消息传递实现的,它的实现是自然同步的,并且不会发生线程争用。
这是一个相关的答案:
Web Worker 没有 DOM 访问权限,因为 DOM 代码不是线程安全的。 DOM 代码是指浏览器中处理您的 DOM 调用的代码。
使线程不安全代码安全是一项巨大的工程,none 的主要浏览器都在这样做。
Servo 项目正在从头开始编写新的浏览器,我认为他们在编写 DOM 代码时考虑了线程安全。
其他答案正确; JS本来就是为了简化而设计成单线程的,此时加入多线程就得非常小心了。我想详细说明 Web Workers 中的线程安全。
当您使用 postMessage
向工作人员发送消息时,会发生以下三种情况之一,
- 浏览器将消息序列化为JSON字符串,并在另一端(在工作线程中)反序列化。这将创建对象的副本。
- 浏览器构建消息的结构化克隆,并将其传递给工作线程。这允许使用比 1. 更复杂的数据类型进行消息传递,但本质上是一样的。
- 浏览器转移消息(或消息的一部分)的所有权。这仅适用于某些数据类型。它是零拷贝,但是一旦主上下文将消息传输到工作上下文,它就在主上下文中变得不可用。这也是为了避免共享内存。
当涉及 DOM 个节点时,
- 显然不是一个选项,因为DOM节点包含循环引用,
- 可以工作,但在只读模式下,因为工作人员对节点克隆所做的任何更改都不会反映在 UI 和
中
不幸的是,- 不是一个选项,因为 DOM 是一棵树,转移节点的所有权将意味着转移整棵树的所有权。如果 UI 线程需要咨询 DOM 来绘制屏幕并且它没有所有权,这会造成问题。
我们都知道我们可以启动一些网络工作者,给他们一些平凡的任务来完成并在某个时候得到响应,在这个阶段我们通常会解析数据并以某种方式将其呈现给用户。
嗯...谁能提供一个相对深入的解释来说明为什么 Web Worker 无法访问 DOM?鉴于经过深思熟虑的 OO 设计方法,我只是不明白为什么他们不应该这样做?
已编辑:
我知道这是不可能的,也没有实际的答案,但我觉得我需要更深入的解释。如果您觉得与社区无关,请随时关闭问题。
浏览器中 Javascript 的整个世界最初设计时进行了极大的简化 - 单线程(在有 webWorkers 之前)。这个单一的假设使浏览器的编码变得更加简单,因为永远不会有线程争用,也永远不会有 activity 的两个线程试图同时修改相同的对象或属性。这使得在浏览器中编写 Javascript 和在浏览器中实现 Javascript 变得更加简单。
然后,需要能够做一些更长的 运行 "background" 类型的事情,而不会阻塞主线程。好吧,将它放入现有浏览器中的唯一实用方法是确保 Javascript 的 "new" 线程能够永远不要搞乱现有的主线程。
因此,它的实现方式是它可以与主线程或主线程可以修改的任何对象(例如整个 DOM 和几乎所有主机对象)进行通信的唯一方式) 是通过消息传递实现的,它的实现是自然同步的,并且不会发生线程争用。
这是一个相关的答案:
Web Worker 没有 DOM 访问权限,因为 DOM 代码不是线程安全的。 DOM 代码是指浏览器中处理您的 DOM 调用的代码。
使线程不安全代码安全是一项巨大的工程,none 的主要浏览器都在这样做。
Servo 项目正在从头开始编写新的浏览器,我认为他们在编写 DOM 代码时考虑了线程安全。
其他答案正确; JS本来就是为了简化而设计成单线程的,此时加入多线程就得非常小心了。我想详细说明 Web Workers 中的线程安全。
当您使用 postMessage
向工作人员发送消息时,会发生以下三种情况之一,
- 浏览器将消息序列化为JSON字符串,并在另一端(在工作线程中)反序列化。这将创建对象的副本。
- 浏览器构建消息的结构化克隆,并将其传递给工作线程。这允许使用比 1. 更复杂的数据类型进行消息传递,但本质上是一样的。
- 浏览器转移消息(或消息的一部分)的所有权。这仅适用于某些数据类型。它是零拷贝,但是一旦主上下文将消息传输到工作上下文,它就在主上下文中变得不可用。这也是为了避免共享内存。
当涉及 DOM 个节点时,
- 显然不是一个选项,因为DOM节点包含循环引用,
- 可以工作,但在只读模式下,因为工作人员对节点克隆所做的任何更改都不会反映在 UI 和 中 不幸的是,
- 不是一个选项,因为 DOM 是一棵树,转移节点的所有权将意味着转移整棵树的所有权。如果 UI 线程需要咨询 DOM 来绘制屏幕并且它没有所有权,这会造成问题。