Web Worker:一种在与当前主(窗口)线程不同的线程中在后台运行脚本的方法。
JavaScript 通常通过将任务放入相应的队列(宏任务队列、微任务队列)来处理异步操作,事件循环不断检查这些队列,并在任务准备好执行时将其推送到调用堆栈中。这种方法确保非阻塞执行,但仍然在单个线程上运行所有内容。
另一方面,Web Workers 允许脚本在完全独立的线程中运行,具有自己的调用堆栈、异步队列和事件循环。这种分离可以防止主线程被繁重的计算或长时间运行的任务阻塞,因为工作线程独立运行。
Web Worker 在与主窗口上下文不同的上下文中执行脚本,从而实现 Web 应用程序中的并行性。 Web Worker API 提供了几种类型的 Worker:
本文重点介绍专用工作者,这是最容易实现且最常用的。
要创建 Web Worker,您可以使用以下关键方法:
让我们创建一个工作程序来从 API 获取数据,特别是从 Dog CEO API 获取狗图像。
这是工作脚本的实现。请注意,在worker内部,self用于引用全局上下文:
if (window.Worker) { const worker = new Worker("/src/worker.js"); worker.postMessage({ operation: "get_dog_imgs", url: "https://dog.ceo/api/breeds/image/random", count: 5 //number of photos }); worker.onmessage = (e) => { console.log(e.data); if (e && e.data) { setdata((old) => [...old, e.data]); // update react state showCallStack(); // function to show the callstack } }; worker.onerror = (e) => { console.log(e); }; }
在此代码中,worker 侦听消息 (onmessage) 并根据计数指定多次从给定 URL 获取数据。
这是工作线程内部的调用堆栈:
主线程像这样使用worker:
self.onmessage = (event) => { const data = event.data; if (data && data.url && data.count) { fetchFromUrls(data.url, data.count); } } // fetch single data const fetchdata = async (url) => { const res = await self.fetch(url); return await res.json(); }; const fetchFromUrls = async (url, count) => { showCallStack(); // showing the callstack of the worker for (const i of new Array(count).fill(0)) { let data = await fetchdata(url); if (data && data.message) { self.postMessage({ type: "img", data: data.message }); } } };
此代码演示了如何向工作线程发送消息并在主线程中接收获取的数据。
完整代码请访问代码
虽然 Web Worker 在与主窗口线程不同的线程中运行,但它们有一定的限制:
以上是使用 Web Workers 在 JS 中实现多线程的详细内容。更多信息请关注PHP中文网其他相关文章!