Web Worker 和 WebSocket的区别
Web Worker(消息传递机制)
- 定义:是为了在浏览器中提供多线程支持,允许 JavaScript 在后台线程运行,而不阻塞主线程。它非常适合执行耗时的计算任务或处理大量数据,避免主线程(通常是 UI 线程)被阻塞,从而保证用户界面的流畅性。
- 应用:运行后台任务,执行长时间运行的计算或操作,诸如图像处理、文件处理、大数据分析等。它并不直接与网络通信或实时消息传递相关。
- 原理:创建Web Worker分配一个新的线程(即后台线程),它一个独立的执行上下文,和主线程相互隔离,且不能直接操作 DOM 或访问主线程中的变量,它和主线程之间的通信是异步的,通常是通过
postMessage
和onmessage
方法进行数据传输。// 创建一个 Worker const worker = new Worker('worker.js'); // 发送消息到 Worker worker.postMessage({ type: 'start', data: 1000 }); // 1000ms 的间隔 // 接收 Worker 返回的消息 worker.onmessage = (event) => { console.log(event.data); // 输出 Worker 返回的数据 }; // 停止 Worker worker.postMessage({ type: 'stop' });
应用计时器:
// worker.js
let setIntervaler = null
let count = 0
// 启动定时器
function start(timeout) {
setIntervaler = setInterval(() => {
postMessage({
type: 'next',
data: ++count
})
}, timeout)
}
// 停止定时器并关闭 Worker
function stop() {
clearInterval(setIntervaler)
count = 0 // 重置计数
self.close() // 关闭 Worker
}
// 监听来自主线程的消息
self.addEventListener('message', (e) => {
let { type, data } = e.data // 解构消息数据
switch (type) {
case 'start':
start(data) // 启动定时器
break
case 'stop':
stop() // 停止定时器
break
default:
break
}
})
<template>
<div>
<h1>Web Worker 定时器</h1>
<p>计数: {{ count }}</p>
<button @click="startTimer" :disabled="isRunning">启动定时器</button>
<button @click="stopTimer" :disabled="!isRunning">停止定时器</button>
</div>
</template>
<script setup>
import { ref, onUnmounted } from 'vue';
// 定义 Vue 组件的状态
const count = ref(0);
const isRunning = ref(false);
// 创建 Worker 实例
// src\utils\worker.js
const worker = new Worker(new URL('../utils/worker.js', import.meta.url));
// 监听 Worker 返回的数据
worker.onmessage = (e) => {
const { type, data } = e.data;
switch (type) {
case 'ready':
console.log(data); // Worker 已准备好
break;
case 'next':
count.value = data; // 更新计数器
break;
default:
break;
}
};
// 启动定时器
const startTimer = () => {
worker.postMessage({ type: 'start', data: 1000 }); // 1000 毫秒(1秒)为定时器间隔
isRunning.value = true; // 更新状态为运行中
};
// 停止定时器
const stopTimer = () => {
worker.postMessage({ type: 'stop' });
isRunning.value = false; // 更新状态为停止
};
// 清理 Worker 实例
onUnmounted(() => {
worker.terminate(); // 组件销毁时终止 Worker
});
</script>
<style scoped>
button {
margin: 10px;
padding: 10px;
font-size: 16px;
}
</style>
WebSocket(握手连接通信)
- 定义:是一种在客户端和服务器之间建立持久连接的协议,它允许双方在连接建立后进行双向实时通信。WebSocket 主要用于需要实时数据更新的应用场景,如实时聊天、在线游戏、股票行情、推送通知等
- 应用:客户端和服务器之间可以保持一个长连接,允许实时交换数据,适合实时应用程序的场景。
- 原理:用 HTTP 协议进行握手建立连接,通信将转为基于 TCP 的实时双向通信(全双工通信),可以随时从客户端或服务器端通过
send
方法发送数据,通过onmessage
监听接收到的消息。// 创建 WebSocket 连接 const socket = new WebSocket('ws://example.com/socket'); // 连接成功后发送消息 socket.onopen = () => { socket.send('Hello, server!'); }; // 接收来自服务器的消息 socket.onmessage = (event) => { console.log('Message from server:', event.data); }; // 发送消息给服务器 socket.send('Another message'); // 关闭连接 socket.close();
总结:
特性 | Web Worker | WebSocket |
主要目的 | 后台线程处理计算任务,避免阻塞主线程 | 双向实时通信,实时数据交换 |
通信方式 | 主线程与 Worker 通过消息传递 | 客户端与服务器之间的持久连接,双向通信 |
适用场景 | 长时间运行的计算任务,数据处理 | 实时应用程序,如聊天、推送通知、在线游戏 |
通信延迟 | 主要用于计算任务,没有即时通信需求 | 适合低延迟、高实时性的双向通信 |
关闭方式 | worker.terminate() 或 self.close() | socket.close() |
追更:
Web Worker 是一个独立的线程,当你调用 self.close()
时,Worker 被终止,所有的状态(如定时器)也会丢失。
因此,想要再次启动定时器则不关闭Worker直到组件被销毁!!!
// worker.js
let setIntervaler = null;
let count = 0;
let isRunning = false; // 标志定时器是否正在运行
// 启动定时器
function start(timeout) {
if (!isRunning) {
isRunning = true; // 标记定时器已启动
setIntervaler = setInterval(() => {
postMessage({
type: 'next',
data: ++count
});
}, timeout);
}
}
// 停止定时器
function stop() {
if (isRunning) {
clearInterval(setIntervaler);
isRunning = false; // 标记定时器已停止
}
}
// 监听来自主线程的消息
self.addEventListener('message', (e) => {
const { type, data } = e.data;
switch (type) {
case 'start':
start(data); // 启动定时器
break;
case 'stop':
stop(); // 停止定时器
break;
default:
break;
}
});
<template>
<div>
<h1>Web Worker 定时器</h1>
<p>计数: {{ count }}</p>
<button @click="startTimer" :disabled="isRunning">启动定时器</button>
<button @click="stopTimer" :disabled="!isRunning">停止定时器</button>
</div>
</template>
<script setup>
import { ref, onUnmounted } from 'vue';
// 定义 Vue 组件的状态
const count = ref(0);
const isRunning = ref(false);
// 创建 Worker 实例,保持 Worker 持续存在
const worker = new Worker(new URL('../utils/worker.js', import.meta.url));
// 监听 Worker 返回的数据
worker.onmessage = (e) => {
const { type, data } = e.data;
switch (type) {
case 'ready':
console.log(data); // Worker 已准备好
break;
case 'next':
count.value = data; // 更新计数器
break;
default:
break;
}
};
// 启动定时器
const startTimer = () => {
if (!isRunning.value) {
worker.postMessage({ type: 'start', data: 1000 }); // 1000 毫秒(1秒)为定时器间隔
isRunning.value = true; // 更新状态为运行中
}
};
// 停止定时器
const stopTimer = () => {
if (isRunning.value) {
worker.postMessage({ type: 'stop' });
isRunning.value = false; // 更新状态为停止
}
};
// 清理 Worker 实例
onUnmounted(() => {
worker.terminate(); // 组件销毁时终止 Worker
});
</script>
<style scoped>
button {
margin: 10px;
padding: 10px;
font-size: 16px;
}
</style>
原文地址:https://blog.csdn.net/m0_72030584/article/details/144114337
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!