前端实时数据刷新全方案详解|WebSocket / 定时轮询 / 惰性轮询 / Web Worker/SharedWorker/ 后台静默同步

前端实时数据刷新全方案详解|WebSocket / 定时轮询 / 惰性轮询 / Web Worker/SharedWorker/ 后台静默同步

文章目录

请添加图片描述

websocket

  • 一次握手 → 永久保持连接(直到主动关闭)
  • 双向通信:客户端 ↔ 服务器 随时互发消息
  • 服务器有新数据 → 立刻推给前端
  • 真正实时刷新数据
// 连接 WebSocketconst ws =newWebSocket('ws://localhost:8080/ws');// 收到服务端推送的新数据,自动刷新页面 ws.onmessage=(e)=>{const newData =JSON.parse(e.data);renderPage(newData);};// 发生错误/关闭 ws.onerror=()=>{}; ws.onclose=()=>{};

定时轮询(setInterval)

定时轮询是前端实现自动刷新数据最基础、最广为人知的方案。它通过 setInterval 定时器,每隔一段时间就向服务器发送一次请求,从而实现页面数据的自动更新。

// 1. 定义数据请求函数asyncfunctionfetchData(){try{const res =awaitfetch('/api/your-data-endpoint');const data =await res.json();updateUI(data);// 更新页面}catch(err){ console.error('请求数据失败:', err);}}// 2. 设置定时器,每 3 秒(3000ms)请求一次const intervalId =setInterval(fetchData,3000);// 3. 定义更新页面的方法(根据你的框架或原生DOM操作)functionupdateUI(newData){// 例如 Vue: this.list = newData;// 例如 原生: document.getElementById('data-container').innerText = newData.value; console.log('数据已更新:', newData);}

页面离开或不再需要轮询时,必须清除定时器,否则会造成内存泄漏。

// 清除定时器的两种常见时机// 方式1:在某个事件中清除(如点击按钮)functionstopPolling(){clearInterval(intervalId); console.log('已停止轮询');}// 方式2:在页面卸载时清除(推荐) window.addEventListener('beforeunload',()=>{clearInterval(intervalId);});

惰性轮询(setTimeout 递归)

setInterval 有一个致命缺点:如果接口请求耗时超过了定时时间,会导致多个请求堆积,阻塞主线程或造成服务器压力。
惰性轮询(递归 setTimeout)能完美解决这个问题。它的规则是:等上一次请求完成(成功或失败)后,再延迟指定时间,发起下一次请求。

let timerId =null;// 定义轮询函数asyncfunctionpolling(){try{const res =awaitfetch('/api/your-data-endpoint');const data =await res.json();updateUI(data);}catch(err){ console.error('请求失败:', err);}finally{// 关键:无论成功失败,3秒后再执行下一次 timerId =setTimeout(polling,3000);}}// 启动轮询polling();// 停止轮询functionstopPolling(){clearTimeout(timerId);}
优缺点
特性setInterval (定时轮询)setTimeout (惰性轮询)
执行逻辑固定时间间隔执行,不受请求耗时影响上一次完成后,延迟固定时间再执行
请求堆积风险(请求慢时会堆积)(串行执行,安全)
适用场景短请求、对时序要求不高的简单场景绝大多数业务场景(推荐)
代码复杂度简单稍复杂(需使用 finally

Web Worker 轮询

Web Worker 最大作用:开一个独立后台线程,不受主线程阻塞、页面切后台也不会被浏览器严重节流,用来做轮询非常稳,是普通项目里最实用的常驻刷新方案。

为什么要用 Web Worker 做轮询?

普通 setInterval 缺点:

  • 页面切后台 → 浏览器会节流 / 变慢 / 暂停定时器
  • JS 执行卡顿、渲染阻塞 → 定时器不准
  • 大量计算时,轮询直接 “卡住不执行”

Web Worker 优点:

  • 独立线程,不阻塞主线程
  • 切后台、页面隐藏依然相对稳定执行
  • 不会被 DOM 渲染、JS 阻塞影响
  • 兼容性极好(IE10+、所有现代浏览器都支持
vue2 写法

安装依赖

npm install worker-loader -D 

vue.config.js 配置

module.exports = { configureWebpack: { module: { rules: [ { test: /\.worker\.js$/, use: { loader: 'worker-loader' } } ] } } } 

创建 src/utils/poll.worker.js

// 后台轮询线程let timer =null// 接收主线程消息 self.onmessage=(e)=>{const{ type, interval }= e.data // 开始轮询if(type ==='start'){clearInterval(timer) timer =setInterval(async()=>{try{// 请求接口const res =awaitfetch('/api/notice')const data =await res.json()// 发给 Vue 页面 self.postMessage({status:'success', data })}catch(err){ self.postMessage({status:'error',msg: err.message })}}, interval)}// 停止if(type ==='stop'){clearInterval(timer)}}

页面使用(Vue2 示例)

import PollWorker from'@/utils/poll.worker.js'exportdefault{mounted(){this.worker =newPollWorker()this.worker.onmessage=(e)=>{ console.log('新数据:', e.data.data)// this.list = e.data.data}this.worker.postMessage({type:'start',interval:3000})},beforeDestroy(){this.worker.postMessage({type:'stop'})this.worker.terminate()}}
Vue3 + Vite 写法(最常用)

Vite 内置支持 Web Worker,超级简单。

<script setup>import{ onMounted, onUnmounted }from'vue'// 直接引入 Worker(Vite 语法)import PollWorker from'@/utils/poll.worker?worker'let worker =nullonMounted(()=>{// 1. 创建 Worker worker =newPollWorker()// 2. 监听后台返回的新数据 worker.onmessage=(e)=>{if(e.data.status ==='success'){ console.log('后台刷新数据:', e.data.data)// 这里更新 Vue 数据 → 页面自动刷新// list.value = e.data.data}}// 3. 启动轮询:3 秒一次 worker.postMessage({type:'start',interval:3000})})// 页面销毁时关闭 WorkeronUnmounted(()=>{if(worker){ worker.postMessage({type:'stop'}) worker.terminate()// 销毁线程}})</script>
使用场景

页面切到后台 / 最小化,你依然希望轮询稳定执行

  • 比如后台管理系统、监控页面、客服系统
  • 用户切走窗口、最小化,普通 setInterval 会被浏览器节流、变慢、甚至暂停
  • Worker 不会被轻易暂停,能保持基本定时精度

页面本身很卡、JS 执行重,定时器不准

  • 大数据表格渲染、图表、大量 DOM 操作
  • 主线程一卡,定时器就 “跳秒”
  • Worker 是独立线程,不受主线程卡顿影响

worker 在使用结束后必须销毁,否则会导致内存泄露问题

Periodic Background Sync

它是浏览器级别的定时任务调度器,基于 Service Worker 运行,不受页面生命周期影响,专门用于后台定时同步数据。
Periodic Background Sync(周期性后台同步) 是专为 PWA 设计的、能在页面完全关闭后仍在后台定时执行网络任务的浏览器 API,完美解决你之前担心的 Worker 销毁、后台轮询失效问题。

核心机制
  • 注册:在 Service Worker 注册时,指定唯一标签(tag)和最小间隔(minInterval)。
  • 调度:浏览器内核接管计时,在设备联网、充电、闲置等低干扰时机触发。
  • 执行:唤醒 Service Worker,触发 periodicsync 事件,执行同步逻辑。
  • 持久化:注册后跨会话生效,直到主动取消。
代码示例

注册(主线程)

// 等待 Service Worker 就绪 navigator.serviceWorker.ready.then(async(registration)=>{// 检查支持if(!registration.periodicSync)return;try{// 注册:每 4 小时同步一次(最小间隔)await registration.periodicSync.register('order-sync',{minInterval:4*60*60*1000// 14400000ms}); console.log('周期性同步注册成功');}catch(err){ console.error('注册失败(权限/浏览器限制)', err);}});

监听与执行(Service Worker)

// sw.js self.addEventListener('periodicsync',(event)=>{if(event.tag ==='order-sync'){// 必须用 waitUntil 保证任务完成 event.waitUntil(fetch('/api/order/sync').then(res=> res.json()).then(data=>{// 缓存新数据、更新 IndexedDB 等return caches.open('order-cache').then(cache=>{return cache.put('/api/order/latest',newResponse(JSON.stringify(data)));});}).catch(err=> console.error('同步失败', err)));}});
  • 浏览器支持:Chrome、Edge 支持;Firefox、Safari 暂不支持。
  • 权限要求:需用户授予 “后台同步” 权限。
  • 触发不保证:minInterval 是下限,浏览器会根据用户活跃度、电量、网络等策略调整,低活跃应用可能很久不触发。
  • 网络限制:仅在已连接过的 Wi-Fi / 蜂窝网络下触发,陌生网络不执行。
  • 任务时长:Service Worker 有超时限制(通常几分钟),长任务需拆分。

requestIdleCallback

requestIdleCallback(简称 rIC)是浏览器提供的主线程闲时调度 API,专门用来执行非紧急、非阻塞的后台任务,避免长任务卡住渲染与交互。
把不重要的任务见缝插针地放在浏览器空闲时段执行,优先保障渲染、动画、用户输入的流畅度。
二、核心原理
浏览器每帧(约 16ms)的工作

  • JS 执行 → 样式计算 → 布局 → 绘制 → 合成
  • 如果一帧提前完成(比如只用了 10ms),剩余时间就是空闲时段
  • requestIdleCallback 回调就在这个时段执行

回调会收到一个 deadline 对象

  • deadline.timeRemaining():当前空闲周期还剩多少毫秒(动态)
  • deadline.didTimeout:是否因超时被强制执行
// 注册一个空闲回调const handle =requestIdleCallback((deadline)=>{// 只要还有空闲时间,就处理任务while(deadline.timeRemaining()>0&& taskQueue.length >0){const task = taskQueue.shift();doHeavyWork(task);// 单次任务要轻}// 没做完,下次空闲继续if(taskQueue.length >0){requestIdleCallback(handle);}},{timeout:2000// 可选:2秒内没空闲就强制执行});// 取消// cancelIdleCallback(handle);

SharedWorker

SharedWorker = 可以被多个标签页 / 多个窗口共享的同一个后台线程
这是它和普通 WebWorker 最核心的区别。
优点

  • 全局轮询、多页同步、避免重复请求
  • 多页面共享同一个
  • 最后一个页面关闭 → 才销毁
  • 基于 port 通信

代码示例
共享线程文件:shared.worker.js

let timer =null;let ports =[];// 连接 self.onconnect=(e)=>{const port = e.ports[0]; ports.push(port);// 监听页面消息 port.onmessage=(e)=>{if(e.data ==='start'){startPoll();}}; port.start();};// 全局唯一轮询functionstartPoll(){if(timer)return; timer =setInterval(async()=>{const res =awaitfetch('/api/notice');const data =await res.json();// 发给所有页面 ports.forEach(port=>{ port.postMessage(data);});},3000);}

页面中使用(任意页面都一样)

const worker =newSharedWorker('/shared.worker.js');const port = worker.port;// 开启 port.start();// 接收共享 Worker 发来的数据 port.onmessage=(e)=>{ console.log('新消息:', e.data);};// 启动轮询 port.postMessage('start');

Read more

ROS1机器人SLAM系列(四):Gmapping算法详解与实战

ROS1机器人SLAM系列(四):Gmapping算法详解与实战 本文将深入讲解Gmapping算法的原理,并通过实战演示如何使用Gmapping进行2D激光SLAM建图。 1. Gmapping算法简介 1.1 什么是Gmapping? Gmapping是一种基于**粒子滤波(Rao-Blackwellized Particle Filter, RBPF)**的2D激光SLAM算法。它由Giorgio Grisetti等人于2007年提出,是ROS中最经典、应用最广泛的SLAM算法之一。 主要特点: * 基于粒子滤波的概率框架 * 适用于2D激光雷达 * 需要里程计信息 * 实现成熟,稳定可靠 * 适合中小规模室内环境 1.2 算法流程概述 Gmapping算法流程 里程计数据 运动预测 Motion Model 粒子集合更新 激光雷达数据 扫描匹配 Scan Matching 观测更新 Sensor Model 粒子权重计算 重采样 Resample 地图更新 2. 核心算法原理

宇树G1机器人强化学习训练完整实战教程

宇树G1机器人强化学习训练完整实战教程

0. 前言 人形机器人的运动控制一直是机器人领域的重要挑战,而强化学习为解决这一问题提供了强有力的工具。本教程将基于宇树G1人形机器人,从基础的强化学习环境搭建开始,逐步深入到高自由度模型的训练配置、奖励函数设计与优化,最终实现复杂动作的训练控制。作者看到一个很棒的系列,所以针对性的对文章内容进行了整理和二次理解,方便大家更好的阅读《不同自由度的宇树G1机器人强化学习训练配置及运行实战 + RSL-RL代码库问题修复》、《宇树G1机器人强化学习训练奖励函数代码架构 + 创建新的奖励函数(1)》、《RL指标分析与看板应用 — 宇树G1机器人高自由度模型强化学习训练实战(3)》、《调参解析 — 宇树G1机器人高自由度模型强化学习训练实战(4)》、《舞蹈训练?手撕奖励函数 — 宇树G1机器人高自由度模型强化学习训练实战(5)》。 1. 强化学习训练环境配置 1.1 基础环境搭建 宇树机器人的强化学习训练基于Isaac Gym物理仿真环境和RSL-RL强化学习框架。首先需要确保这两个核心组件正确安装和配置。 在开始训练之前,我们通过简单的命令来启动12自由度G1机器人的基础训练:

【GitHub开源AI精选】OpenGlass:大模型赋能的开源方案,25美元打造智能眼镜,支持语音控制+AR叠加

【GitHub开源AI精选】OpenGlass:大模型赋能的开源方案,25美元打造智能眼镜,支持语音控制+AR叠加

系列篇章💥 No.文章1【GitHub开源AI精选】LLM 驱动的影视解说工具:Narrato AI 一站式高效创作实践2【GitHub开源AI精选】德国比勒费尔德大学TryOffDiff——高保真服装重建的虚拟试穿技术新突破3【GitHub开源AI精选】哈工大(深圳)& 清华力作 FilmAgent:剧本自动生成 + 镜头智能规划,开启 AI 电影制作新时代4【GitHub开源AI精选】Lumina - Image 2.0 文生图模型,以小参数量实现高分辨率多图生成新突破5【GitHub开源AI精选】探索 Mobile-Agent:X-PLUG 推出的创新型移动智能操作代理6【GitHub开源AI精选】吴恩达团队开源VisionAgent:用自然语言开启计算机视觉新时代7【GitHub开源AI精选】Oumi:一站式AI开发平台,涵盖训练、评估与部署全流程8【GitHub开源AI精选】深入剖析RealtimeSTT:开源实时语音转文本库的强大功能与应用9【GitHub开源AI精选】PodAgent:多智能体协作播客生成框架,

无人机地面站QGC的安装(ubuntu20.04)

无人机地面站QGC的安装(ubuntu20.04) 1.安装依赖 使用以下命令: sudo usermod -a -G dialout $USER sudo apt-get remove modemmanager -y sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl -y sudo apt install libfuse2 -y sudo apt install libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor0 -y 2.下载安装包 可以直接去官网下载,链接地址:https://docs.qgroundcontrol.com/master/en/qgc-user-guide/