前言
在公司 js 社区的讨论中,有一位同学遇到了这样一个需求,在 react 应用中按需加载了一些 js 文件,这些文件有可能加载失败,需要获取到这些失败的文件状态码,做出相应的处理,那么问题来了,怎么获取状态码呢?
不可取的方式
同事 [a,b,c,d,e] 纷纷重拳出击,看他们都说到了 react 的底层实现了,却没一个回答问题同事 f 说到 直接发一个 fetch 请求
1 | const url = '?'; |
其实这会有两个问题
- 如何获取 当前请求资源的
url - 页面加载本身会有次资源请求,再次
fetch去获取会发两次请求
浏览器的 4 个线程
浏览器的运行机制 本身会有 4 个线程,用来处理不同的事情
主线程渲染 dom 执行 js 之类的工作线程Web Worker 和 Service Worker- 排版线程
- 光栅线程
后面两个线程我不太熟悉就不乱说了 O Web Worker 可以用来做一些密集计算 然后使用 postMessage 发送给主线程 Service Worker 是 PWA 的核心,可以读取缓存,拦截 fetch 请求, 做本地推送 (web push), 离线应用 等等很多炫酷的事情其中拦截 fetch 请求就可以解决这位同学的问题
注册一个 Service Worker
1 | // index.html |

如同所示 在应用启动的时候 register 了 一个 Service Worker, 这个兄弟从此开始默默的陪伴着我们,下一步就是让他帮我们拦截请求
拦截请求
1 | self.addEventListener('fetch', (event) => { |
这里有几点需要注意
self 表示当前线程的一个作用域
event.waitUntil 参考 MDN
在一个与 install 事件相关联的 EventHandler 被调用时,它延迟将被安装的 worker 视为 installing ,直到传递的 Promise 被成功地 resolve。这主要用于确保:服务工作线程在所有依赖的核心 cache 被缓存之前都不会被安装
client.postMessage 这里和 web worker 有一点不一样不能直接 self.postMessage, 需要拿到当前 主线程的 实例 才能 postMessage 到 主线程
event.request.url 表示请求的 url 如图所示

接收状态码
现在我们已经让 Service Worker 这个大兄弟帮我们把 当前请求资源状态码发过来了,接下来就是”收货”(接收)了。
1 | // 监听 sw 线程发过来的 状态码 |

接下来就可以拿到这个状态码 做对应的业务逻辑了
结语
Service Worker 已经出来很久了,前两年 由于 PWA 火了一把,当时我也是玩了很久,踩了很多坑由于兼容性等等因素,现在又变得不温不火了,不过作为知识储备也是很香的。
