JavaScript 是一种单线程语言,意味着它在一个时间点只能执行一个任务。尽管如此,一个进程可以包含多个线程,例如浏览器中的 Web Worker 提供了一种在后台线程中运行脚本的方式,从而避免主线程被阻塞。
Web Worker 是浏览器提供的一种多线程机制,允许开发者在后台线程中运行 JavaScript 脚本,主要用于以下场景:
谷歌浏览器是一个多进程架构的浏览器,每个进程可以包含多个线程。以下是常见的线程类型及其作用:
线程类型 | 主要任务 |
---|---|
主线程 | 页面渲染、用户交互、JavaScript 执行 |
渲染线程 | 样式计算、布局计算、绘制和合成 |
工作线程 | Web Worker、Service Worker 等后台任务 |
网络线程 | HTTP 请求、WebSocket 通信 |
GPU 线程 | 硬件加速渲染、3D 绘制 |
定时器线程 | setTimeout 、setInterval 等定时任务 |
I/O 线程 | 文件读写、数据库操作 |
音频线程 | 音频播放、音频处理 |
以下是一个简单的 Web Worker 示例,用于在后台线程中计算大数的阶乘:
new Worker(js文件)
const worker = new Worker('worker.js');
worker.postMessage(10); // 向 Worker 发送数据
worker.onmessage = (event) => {
console.log(`阶乘结果: ${event.data}`);
};
// 计算阶乘函数
function factorial(n) {
if (n === 0 || n === 1) return 1;
return n * factorial(n - 1);
}
// 接收主线程发送的数据
onmessage = (e) => {
const result = factorial(e.data); // 计算 e.data 的阶乘
postMessage(result); // 将结果发送回主线程
};
worker.terminate()
onerror =(meeage,filename,lineno)=>{
}
worker 能够生成更多的 worker
importScripts(); /* 什么都不引入 */
importScripts("foo.js"); /* 只引入 "foo.js" */
importScripts("foo.js", "bar.js"); /* 引入两个脚本 */
importScripts("//example.com/hello.js"); /* 你可以从其他来源导入脚本 */
const myWorker = new SharedWorker("worker.js");
myWorker.port.postMessage([first.value, second.value]);
onconnect = (event)=>{
const port = e.event[0]
port.onmessage=(e)=>{
// e.data
}
}
f12 下 source / worker可见
在一个 worker 中最主要的你不能做的事情就是直接影响父页面。包括操作父页面的节点以及使用页面中的对象
参考 Web Worker API
react-useworker
是一个 React Hook 库,用于简化 Web Worker 的使用。它允许开发者轻松地将耗时的计算任务移到后台线程中,从而提高应用的性能。
npm install react-useworker
import useWorker from 'react-useworker';
const App = () => {
const [workerFn, { kill }] = useWorker((num) => {
const factorial = (n) => (n <= 1 ? 1 : n * factorial(n - 1));
return factorial(num);
});
const handleCalculate = async () => {
const result = await workerFn(10);
console.log(`阶乘结果: ${result}`);
};
return (
<div>
<button onClick={handleCalculate}>计算阶乘</button>
<button onClick={kill}>终止 Worker</button>
</div>
);
};
export default App;
在 Vue 3 中,可以通过 worker-loader
和 Web Worker 来处理耗时任务。以下是一个使用 Web Worker 的 Vue 3 示例:
在 webpack.config.js
中添加以下配置:
module.exports = {
module: {
rules: [
{
test: /\.worker\.js$/,
use: { loader: 'worker-loader' },
},
],
},
};
创建一个 Worker 文件 factorial.worker.js
:
// factorial.worker.js
onmessage = (e) => {
const factorial = (n) => (n <= 1 ? 1 : n * factorial(n - 1));
postMessage(factorial(e.data));
};
在 Vue 3 组件中使用 Web Worker:
阶乘结果: {{ result }}
这两个库可以帮助开发者更高效地使用 Web Worker,简化复杂任务的实现。
→