网站建设与维护黄石网站建设

奇异湾(杭州)科技有限公司 2026/09/09 19:29:57

本文对比了服务工作者线程(Service Worker)生命周期中的关键事件和属性,包括注册、安装、激活和控制各阶段。


通过详细表格展示了不同事件的触发时机、监听位置(主线程/服务线程)和典型用途,并重点分析了事件是否立即生效的特性差异。


文章还提供了实际代码示例,说明如何正确处理异步操作(如waitUntil和respondWith),确保服务工作者线程生命周期管理的可靠性。


最后总结了不同生效时机的适用场景,帮助开发者优化离线应用的用户体验和功能实现。


服务工作者线程生命周期事件/属性对比表

阶段事件/属性监听位置触发时机典型用途
注册阶段navigator.serviceWorker.register()主线程注册服务工作者脚本首次注册或更新SW
registration对象主线程注册成功后返回管理SW更新、订阅等
安装阶段install事件服务线程SW脚本首次下载或检测到更新时预缓存资源、初始化DB
registration.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 等事件◄─处理事件─────▶│

重要区别总结

  1. 位置不同

    • 主线程:管理SW注册、更新和状态监控

    • 服务线程:处理具体功能逻辑(缓存、推送等)

  2. 时机不同

    • 主线程事件关注SW与页面的关系变化

    • 服务线程事件关注SW自身状态和功能执行

  3. 控制权不同

    • 主线程可以主动触发更新、跳过等待

    • 服务线程控制资源缓存和请求处理


服务工作者线程事件对比表

事件名称触发时机主要用途是否立即生效典型场景
controllerchangenavigator.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')); });

生命周期顺序

  1. 检测到新版本 →updatefound事件

  2. 安装完成后等待激活 → (无特定事件)

  3. 激活成功 →activate事件(服务工作者已就绪)

  4. 控制页面 →controllerchange事件(页面已被控制)


重要区别

  • updatefoundactivate在服务工作者线程内监听

  • controllerchange在客户端页面(主线程)中监听

  • updatefound表示"发现更新",activate表示"准备就绪",controllerchange表示"已接管控制"


服务工作者线程生命周期事件/属性对比表(新增“是否立即生效”列)

阶段事件/属性监听位置是否立即生效触发时机典型用途
注册阶段navigator.serviceWorker.register()主线程否(异步)注册服务工作者脚本首次注册或更新SW
registration对象主线程立即注册成功后返回管理SW更新、订阅等
安装阶段install事件服务线程是,但需等待waitUntil()SW脚本首次下载或检测到更新时预缓存资源、初始化DB
registration.installing主线程立即安装过程中可用检查安装状态
等待阶段registration.waiting主线程立即安装完成等待激活提示用户更新、跳过等待
激活阶段activate事件服务线程是,但需等待waitUntil()SW激活成功,获得控制权清理旧缓存、数据迁移
registration.active主线程立即SW已激活检查激活状态
控制阶段controllerchange事件主线程立即页面被新的SW控制时更新UI、重新加载页面
navigator.serviceWorker.controller主线程立即当前控制页面的SW检查当前控制器
更新检查updatefound事件主线程立即检测到新版本SW开始安装显示更新提示
registration.update()主线程否(异步)手动触发更新检查强制检查更新
就绪状态navigator.serviceWorker.ready主线程否(Promise)SW已激活并准备就绪确保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); // 删除旧缓存 } }) ); }) ); });

关键要点总结

  1. 立即生效:主要用于状态查询和UI更新,不涉及异步操作

  2. 等待 Promise:用于确保操作顺序,避免竞态条件

  3. waitUntil/respondWith:服务线程生命周期管理的关键机制,保证异步操作完成

  4. 实际影响:是否立即生效直接影响用户体验和代码执行逻辑

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

网站建设设计天津网站建设

StatiCrypt主题定制终极指南:打造个性化密码保护界面【免费下载链接】staticryptPassword protect a static HTML page, decrypte

2026/06/30 10:59:53

宝安网站建设松江网站建设

Langchain-Chatchat问答延迟优化:GPU推理加速实测在企业智能客服、内部知识助手等应用场景中,用户早已习惯了“秒回”的交互体验。然而,当我们将

2026/06/30 10:13:49

江门网站建设江苏省建设厅网站

如何快速掌握秒传链接:百度网盘高效文件管理终极指南【免费下载链接】rapid-upload-userscript-doc秒传链接提取脚本 - 文档&教程项目地址: https:/

2026/06/30 10:44:51

电器网站建设南京网站建设公司

快速体验打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容:在快马平台上快速开发一个地区限制检测工具原型。功能包括:输入网

2026/06/30 10:49:52

网站建设服务建设厅网站

FLUX.1-dev FP8量化模型:6GB显存终极AI绘画解决方案【免费下载链接】flux1-dev项目地址: https://ai.gitcode.com/hf_mirrors/Co

2026/06/30 13:42:07

旅游网站建设网站建设电话

快速体验打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容:使用HUMAN3.0提示词快速生成一个完整的Web应用前后端代码࿰

2026/06/30 13:58:08

桂林网站建设网站建设软件

Crawl4AI嵌入策略终极指南:从关键词匹配到语义理解的智能爬取革命【免费下载链接】crawl4ai🔥🕷️ Crawl4AI: Open-source

2026/06/30 11:37:56

合肥网站建设网站正在建设中

23.6 跨团队协作:与技术人员高效沟通的艺术课程概述在上一节课中,我们学习了技术调研方法,了解了如何快速掌握前沿技术动态。本节课我们将探讨跨团队协作的重要话题——与技术人员高效沟通的艺术。作为AIG

2026/06/30 12:24:01

永康网站建设扬州网站建设

220W字详细介绍高级架构师精选面试题库-百万八股面试宝典内容概述本面试宝典是为高级架构师量身打造的综合性面试指南,包含超过220万字的详尽内容,涵盖以下核心领域ÿ

2026/06/30 12:50:33