自学内容网 自学内容网

Web Worker 和 WebSocket的区别

Web Worker(消息传递机制)

  1. 定义:是为了在浏览器中提供多线程支持,允许 JavaScript 在后台线程运行,而不阻塞主线程。它非常适合执行耗时的计算任务或处理大量数据,避免主线程(通常是 UI 线程)被阻塞,从而保证用户界面的流畅性。
  2. 应用:运行后台任务,执行长时间运行的计算或操作,诸如图像处理、文件处理、大数据分析等。它并不直接与网络通信或实时消息传递相关。
  3. 原理:创建Web Worker分配一个新的线程(即后台线程),它一个独立的执行上下文,和主线程相互隔离,且不能直接操作 DOM 或访问主线程中的变量,它和主线程之间的通信是异步的通常是通过 postMessageonmessage 方法进行数据传输。
    // 创建一个 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(握手连接通信)

  1. 定义:是一种在客户端和服务器之间建立持久连接的协议,它允许双方在连接建立后进行双向实时通信。WebSocket 主要用于需要实时数据更新的应用场景,如实时聊天、在线游戏、股票行情、推送通知等
  2. 应用:客户端和服务器之间可以保持一个长连接,允许实时交换数据,适合实时应用程序的场景。
  3. 原理:用 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 WorkerWebSocket
主要目的后台线程处理计算任务,避免阻塞主线程双向实时通信,实时数据交换
通信方式主线程与 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)!