news 2026/2/18 11:27:00

服务工作者线程生命周期各阶段的属性或事件(附:controllerchange updatefound activate对比)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
服务工作者线程生命周期各阶段的属性或事件(附:controllerchange updatefound activate对比)

本文对比了服务工作者线程(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. 实际影响:是否立即生效直接影响用户体验和代码执行逻辑

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

应用层自定义协议

自定义协议和序列化面向字节流全双工自定义协议序列化IO模块socket封装ServerserviceCalClient完整代码接下来我们实现一个网络计算器功能。自定义协议和序列化 前面我们的UDP套接字编程和TCP套接字编程都实现了应用层,但没有实现协议。是否会疑惑有没有协议有何不…

作者头像 李华
网站建设 2026/2/17 18:11:01

8个AI论文工具,助继续教育学生轻松完成写作!

8个AI论文工具,助继续教育学生轻松完成写作! AI 工具如何让论文写作更高效 在当前的继续教育环境中,学生和科研工作者面临越来越多的写作任务,而传统的写作方式往往耗时耗力。随着 AI 技术的不断进步,AI 工具正逐渐成为…

作者头像 李华
网站建设 2026/2/15 7:33:38

国内仿真云平台哪家强?该如何选择?

在数字化与智能化浪潮的推动下,仿真技术已成为工业设计、科学研究和教育培训等领域的重要工具。随着云计算技术的普及,仿真云平台凭借其弹性计算、高效协作和成本优化等优势,受到越来越多企业与机构的青睐。然而,面对国内市场上众…

作者头像 李华
网站建设 2026/2/14 4:01:05

设备OAuth2令牌过期致认证失败 后来启用自动刷新+双令牌热备

💓 博客主页:塔能物联运维的CSDN主页 目录 物联网运维:当我的扫地机器人开始叛逆 物联网运维的日常崩溃 运维自动化:让扫地机器人学会自愈 真实案例:某次失败的智能马桶维修 我的物联网运维三原则 那些年我们踩过的坑 …

作者头像 李华
网站建设 2026/2/4 9:22:51

文章里用了AI生成图片会被谷歌降权吗?

谷歌并不会单纯因为图片是AI生成而惩罚内容​​,真正触发降权的是错误的使用方式。例如:同一套AI模板反复配图、图片加载过慢拖累用户体验,或图文完全脱节被判定为“低质内容”。本文基于谷歌《网页质量指南》和实际流量数据测试,…

作者头像 李华
网站建设 2026/2/5 3:43:14

GraniStudio:相机采图例程

1.文件运行 导入工程 双击运行桌面GraniStudio.exe。 通过引导界面导入相机采图例程,点击导入按钮。 打开相机采图例程所在路径,选中相机采图.gsp文件,点击打开,完成导入。 2.功能说明 实现海康相机连接以及单次采图显示。 注意…

作者头像 李华