2026/1/18 17:33:13
网站建设
项目流程
公司网站首页大图怎么做,seo推广是什么意怿,产品推广图片,网站制作里面链接怎么做本文对比了服务工作者线程#xff08;Service Worker#xff09;生命周期中的关键事件和属性#xff0c;包括注册、安装、激活和控制各阶段。通过详细表格展示了不同事件的触发时机、监听位置#xff08;主线程/服务线程#xff09;和典型用途#xff0c;并重点分析了事件…本文对比了服务工作者线程Service Worker生命周期中的关键事件和属性包括注册、安装、激活和控制各阶段。通过详细表格展示了不同事件的触发时机、监听位置主线程/服务线程和典型用途并重点分析了事件是否立即生效的特性差异。文章还提供了实际代码示例说明如何正确处理异步操作如waitUntil和respondWith确保服务工作者线程生命周期管理的可靠性。最后总结了不同生效时机的适用场景帮助开发者优化离线应用的用户体验和功能实现。服务工作者线程生命周期事件/属性对比表阶段事件/属性监听位置触发时机典型用途注册阶段navigator.serviceWorker.register()主线程注册服务工作者脚本首次注册或更新SWregistration对象主线程注册成功后返回管理SW更新、订阅等安装阶段install事件服务线程SW脚本首次下载或检测到更新时预缓存资源、初始化DBregistration.installing主线程安装过程中可用检查安装状态等待阶段registration.waiting主线程安装完成等待激活提示用户更新、跳过等待激活阶段activate事件服务线程SW激活成功获得控制权清理旧缓存、数据迁移registration.active主线程SW已激活检查激活状态控制阶段controllerchange事件主线程页面被新的SW控制时更新UI、重新加载页面navigator.serviceWorker.controller主线程当前控制页面的SW检查当前控制器更新检查updatefound事件主线程检测到新版本SW开始安装显示更新提示registration.update()主线程手动触发更新检查强制检查更新就绪状态navigator.serviceWorker.ready主线程SW已激活并准备就绪确保SW可用后执行操作功能事件fetch事件服务线程发起网络请求时拦截和处理请求push事件服务线程收到推送消息时显示推送通知sync事件服务线程后台同步触发时同步离线数据错误处理statechange事件主线程SW状态变化时调试状态变化error事件主线程SW脚本加载失败时错误处理和降级详细说明与示例代码主线程监听的事件// 注册服务工作者 const registration await navigator.serviceWorker.register(/sw.js); // 监听控制器变化 navigator.serviceWorker.addEventListener(controllerchange, () { console.log(页面已被新的服务工作者控制); }); // 监听更新发现 registration.addEventListener(updatefound, () { console.log(发现新版本服务工作者); }); // 检查等待中的SW if (registration.waiting) { // 提示用户更新 }服务线程内监听的事件// sw.js 文件内 // 安装事件 self.addEventListener(install, event { event.waitUntil( caches.open(v1).then(cache cache.addAll([/app.css])) ); }); // 激活事件 self.addEventListener(activate, event { event.waitUntil( caches.keys().then(keys Promise.all(keys.map(key caches.delete(key))) ) ); }); // 拦截请求 self.addEventListener(fetch, event { event.respondWith( caches.match(event.request).then(response response || fetch(event.request) ) ); });生命周期流程图主线程 服务线程 │ │ ├─ register(sw.js) ──────────────────────▶│ │ │ │ 返回 registration 对象 │ │ │ │─监听 updatefound ────检测到更新───────────▶│ │ │ │ ├─ install 事件 │ │ (预缓存资源) │ │ │ registration.waiting 变为真 │ │ │ │─调用 skipWaiting() ───跳过等待───────────▶│ │ │ │ ├─ activate 事件 │ │ (清理旧缓存) │ │ │─监听 controllerchange ◀─获得控制权───────▶│ │ (页面被新SW控制) │ │ │ │─navigator.serviceWorker.ready───────────▶│ │ (SW准备就绪) │ │ │ └─监听 fetch/push/sync 等事件◄─处理事件─────▶│重要区别总结位置不同主线程管理SW注册、更新和状态监控服务线程处理具体功能逻辑缓存、推送等时机不同主线程事件关注SW与页面的关系变化服务线程事件关注SW自身状态和功能执行控制权不同主线程可以主动触发更新、跳过等待服务线程控制资源缓存和请求处理服务工作者线程事件对比表事件名称触发时机主要用途是否立即生效典型场景controllerchange当navigator.serviceWorker.controller发生变化时触发检测页面是否被新的服务工作者控制立即生效页面刷新后检测是否由新SW控制更新UI状态updatefound当正在安装的服务工作者开始安装时触发检测到新版本提示用户有更新可用可显示更新提示尚未生效检测到新版本SW显示“有更新可用”提示activate当服务工作者激活成功获得控制权时触发清理旧缓存、迁移数据等准备工作已生效但尚未控制页面删除旧缓存为控制客户端做准备详细说明controllerchange触发条件navigator.serviceWorker.controller属性值改变特点表明页面已被新的服务工作者控制示例使用navigator.serviceWorker.addEventListener(controllerchange, () { console.log(当前页面已被新的服务工作者控制); });updatefound触发条件检测到新的服务工作者脚本并开始安装特点仅表示发现新版本不代表已激活示例使用registration.addEventListener(updatefound, () { console.log(发现新版本服务工作者); });activate触发条件服务工作者成功激活获得控制权特点这是清理旧资源的理想时机但还不能控制现有客户端示例使用self.addEventListener(activate, event { // 清理旧缓存 event.waitUntil(caches.delete(old-cache)); });生命周期顺序检测到新版本 →updatefound事件安装完成后等待激活 → 无特定事件激活成功 →activate事件服务工作者已就绪控制页面 →controllerchange事件页面已被控制重要区别updatefound和activate在服务工作者线程内监听controllerchange在客户端页面主线程中监听updatefound表示发现更新activate表示准备就绪controllerchange表示已接管控制服务工作者线程生命周期事件/属性对比表新增“是否立即生效”列阶段事件/属性监听位置是否立即生效触发时机典型用途注册阶段navigator.serviceWorker.register()主线程否异步注册服务工作者脚本首次注册或更新SWregistration对象主线程立即注册成功后返回管理SW更新、订阅等安装阶段install事件服务线程是但需等待waitUntil()SW脚本首次下载或检测到更新时预缓存资源、初始化DBregistration.installing主线程立即安装过程中可用检查安装状态等待阶段registration.waiting主线程立即安装完成等待激活提示用户更新、跳过等待激活阶段activate事件服务线程是但需等待waitUntil()SW激活成功获得控制权清理旧缓存、数据迁移registration.active主线程立即SW已激活检查激活状态控制阶段controllerchange事件主线程立即页面被新的SW控制时更新UI、重新加载页面navigator.serviceWorker.controller主线程立即当前控制页面的SW检查当前控制器更新检查updatefound事件主线程立即检测到新版本SW开始安装显示更新提示registration.update()主线程否异步手动触发更新检查强制检查更新就绪状态navigator.serviceWorker.ready主线程否PromiseSW已激活并准备就绪确保SW可用后执行操作功能事件fetch事件服务线程是但需等待respondWith()发起网络请求时拦截和处理请求push事件服务线程是但需等待waitUntil()收到推送消息时显示推送通知sync事件服务线程是但需等待waitUntil()后台同步触发时同步离线数据错误处理statechange事件主线程立即SW状态变化时调试状态变化error事件主线程立即SW脚本加载失败时错误处理和降级是否立即生效 详细解释立即生效的情况// 示例1: 立即生效的属性 if (registration.waiting) { // 立即返回true/false // 已有等待中的SW } // 示例2: 立即触发的事件 navigator.serviceWorker.addEventListener(controllerchange, () { // 事件触发后立即执行 window.location.reload(); // 可以立即重新加载页面 });需等待 Promise 的情况// 示例1: 异步操作 navigator.serviceWorker.ready.then(() { // 只有SW完全就绪后才会执行 console.log(SW准备就绪); }); // 示例2: 需要 waitUntil() 的事件 self.addEventListener(install, event { // 必须等待缓存操作完成 event.waitUntil( caches.open(v1).then(cache { return cache.addAll([/app.js, /style.css]); // 异步操作 }) ); // 只有在Promise完成后install才完成 });需等待 respondWith() 的情况self.addEventListener(fetch, event { // 必须调用 respondWith() 并提供Promise event.respondWith( caches.match(event.request).then(response { // 这个Promise完成前页面请求不会得到响应 return response || fetch(event.request); }) ); });不同生效时机的使用场景立即生效→用户界面响应// 立即更新UI状态 registration.addEventListener(updatefound, () { // 立即显示更新提示 showUpdateToast(发现新版本正在下载...); });需等待 Promise→确保操作完成// 确保SW激活后再发送消息 navigator.serviceWorker.ready.then(registration { registration.active.postMessage(SW已就绪开始工作); });需 waitUntil→保证生命周期完整性self.addEventListener(activate, event { // 保证清理完成前SW不会进入下一步 event.waitUntil( caches.keys().then(cacheNames { return Promise.all( cacheNames.map(cacheName { if (cacheName ! current-v2) { return caches.delete(cacheName); // 删除旧缓存 } }) ); }) ); });关键要点总结立即生效主要用于状态查询和UI更新不涉及异步操作等待 Promise用于确保操作顺序避免竞态条件waitUntil/respondWith服务线程生命周期管理的关键机制保证异步操作完成实际影响是否立即生效直接影响用户体验和代码执行逻辑