JavaScript 中 Web Workers 对 DOM 的限制有哪些?


JavaScript 是一种单线程编程语言。这意味着它以循序渐进的方式执行应用程序的所有代码。在某些情况下,我们需要执行计算密集型任务。例如,拥有大型数据库的应用程序需要处理大量数据,这可能比平时花费更多时间。为了在这种情况下提高应用程序性能,我们需要使用多线程,它可以同时运行多个任务。

JavaScript 不支持多线程,但 Web Workers 允许我们在后台运行特定任务,从而提高应用程序的性能和用户体验。但是,在访问 DOM 元素时,使用 Web Workers 有一些限制。下面,我们将讨论 Web Workers 的限制以及解决方案。

Web Workers 对 DOM 的限制

1. Web Workers 无法直接访问 DOM 元素

DOM(文档对象模型)包含网页的结构。我们可以从 DOM 访问网页元素。但是,只有主线程可以访问 DOM 元素并更新它们,而 Web Workers 无法访问 DOM 元素。Web Workers 需要通过消息与主线程通信才能执行任何与 DOM 元素相关的操作。

// This is a web worker code in app.js
// The below code will give an error
let ele = document.getElementById("id");
console.log(ele);

// Main JavaScript code
// This code is correct
let ele = document.getElementById("id");
console.log(ele); 

2. Web Workers 的 DOM 相关功能有限

Web Workers 的 DOM 相关功能有限。我们不能在 Web Workers 中使用 DOM 相关的 API。例如 `fetch()`、`querySelector()`、`getElementById()`、`document`、`window` 等。我们不能在 Web Workers 中使用这些 API 和与窗口相关的对象。如果我们想使用此类 API,我们需要通过消息与主线程通信,并在主线程中使用这些 API 相关的功能。

在下面的代码中,我们可以看到,如果我们在 Web Worker 文件中使用 `window` 或 `document` 对象,则会报错。

// This is a web worker code in app.js
// The below code will give an error
window.addEventListener("load", () => {
   let ele = document.querySelector("#id");
});

// Main JavaScript code
// This code is the correct
window.addEventListener("load", () => {
   let ele = document.querySelector("#id");
});

3. UI 更新受限

Web Workers 不允许更新 UI,因为它们无法访问 DOM 元素。如果我们需要使用 Web Worker 更新 UI,我们可以向主线程发送消息以更新 UI,以便主线程可以访问 DOM 元素并相应地更新它。

// This is a web worker code in app.js
// The below code will give an error
window.addEventListener("load", () => {
   let ele = document.querySelector("#id");
   ele.style.color = "blue";
});

// Main JavaScript code
// This code is the correct
window.addEventListener("load", () => {
   let ele = document.querySelector("#id");
   ele.style.color = "blue";
});

通过 Web Workers 与主线程通信以克服 DOM 限制

克服 Web Workers 与 DOM 相关限制的最佳解决方案是使用 Web Workers 与主线程通信。我们可以使用 Web Workers 处理数据,并通过消息事件将结果数据发送到主线程。因此,主线程可以更新 DOM 元素。

示例

在下面的示例中,我们使用 `postMessage()` 方法将消息从 Web Worker 发送到主线程。

在主线程中,我们使用 `onmessage` 事件来执行回调函数,每当它接收到消息时。我们可以在回调函数中对 DOM 元素执行操作。在这里,我们使用其 ID 访问元素,并使用从 Web Worker 获取的新文本更新其文本内容。

// Web worker file (app.js)
self.postMessage("This is a updated text!");

// Main thread
const app = new Worker("app.js");
app.onmessage = function(event) {

   // Update text in UI
   const para = document.getElementById("text");
   para.textContent = event.data;
};

Web Workers 非常强大,可以并行或在后台执行任务,但是当我们将其与 DOM 一起使用时,我们需要通过与主线程通信来克服其限制。在这里,我们学习了 Web Workers 的三个主要限制以及克服这些限制的解决方案。

更新于:2023年7月14日

453 次浏览

启动您的 职业生涯

完成课程获得认证

开始学习
广告