serviceworker离线缓存依赖异步事件驱动模型,install、fetch、activate阶段均需用event.waituntil()包裹promise链确保时序正确;caches api与fetch均为异步操作,须妥善处理错误与离线兜底。

ServiceWorker 处理离线缓存的核心是异步事件驱动模型,所有关键操作(注册、安装、请求拦截)都依赖 Promise 和 event.waitUntil() 来确保异步任务完成后再进入下一阶段,避免资源未就绪就被使用。
install 阶段的异步缓存预加载
安装时不能直接执行缓存操作,必须用 event.waitUntil() 包裹 Promise 链,让浏览器知道该阶段何时真正完成。否则可能跳过缓存、导致离线失败。
- 调用 caches.open(cacheName) 返回 Promise,打开指定缓存空间
- cache.addAll(urls) 是批量写入操作,内部逐个 fetch 并存入缓存,全程异步且不可中断
- 若某个 URL 请求失败(如 404 或跨域),整个 addAll 会 reject,需捕获错误或预先校验资源可用性
fetch 事件中的异步响应决策
每次网络请求触发 fetch 事件,回调中必须调用 event.respondWith(),它只接受 Promise
- caches.match(request) 异步查询缓存,返回 Promise
,匹配失败时返回 undefined - 后续用逻辑判断:有缓存就直接返回;没有则调用 fetch(request),它也返回 Promise
- 注意:fetch() 在离线时会抛出 TypeError,需在 .catch() 中兜底(比如返回一个 fallback HTML 页面)
activate 阶段的异步缓存清理
激活时清理旧缓存,同样需要 event.waitUntil() 确保清理完毕再完成激活,防止新旧缓存共存造成混乱。
- caches.keys() 获取所有缓存名列表,返回 Promise
- 对每个旧缓存名调用 caches.delete(name),每个 delete 也是 Promise
- 用 Promise.all() 并行执行所有删除,统一等待全部完成
为什么不能用 await 或同步写法
ServiceWorker 全局作用域不支持顶层 await,且禁止同步阻塞操作(如 localStorage、XMLHttpRequest)。所有 I/O 操作(缓存读写、网络请求)必须异步,否则会中断生命周期流程,甚至导致 worker 被终止。
实际开发中,把缓存逻辑封装成可复用的 async 函数反而容易出错——event.waitUntil() 要求传入原生 Promise,不是 async 函数返回的 Promise 就可能被忽略。推荐保持链式 then/catch 或显式构造 Promise。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











