推荐答案
Service Workers 的生命周期包括以下几个阶段:
注册(Registration):通过
navigator.serviceWorker.register()方法注册 Service Worker 脚本。注册成功后,Service Worker 进入安装阶段。安装(Installation):在安装阶段,Service Worker 会触发
install事件。开发者可以在这个阶段缓存静态资源,确保离线可用。激活(Activation):安装完成后,Service Worker 进入激活阶段,触发
activate事件。在这个阶段,开发者可以清理旧的缓存资源。等待(Waiting):如果已经有其他 Service Worker 在控制页面,新的 Service Worker 会进入等待状态,直到所有客户端都关闭或手动跳过等待。
控制(Control):一旦激活成功,Service Worker 将控制页面,并开始拦截网络请求。
终止(Termination):当不再需要时,Service Worker 会被浏览器终止以节省资源。
本题详细解读
1. 注册(Registration)
Service Worker 的生命周期从注册开始。通过调用 navigator.serviceWorker.register() 方法,开发者可以注册一个 Service Worker 脚本。注册成功后,浏览器会下载并解析该脚本。
// www.javascriptcn.com code example
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker 注册成功:', registration);
})
.catch(error => {
console.log('Service Worker 注册失败:', error);
});
}2. 安装(Installation)
在安装阶段,Service Worker 会触发 install 事件。开发者可以在这个阶段缓存静态资源,以便在离线时使用。
// www.javascriptcn.com code example
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache => {
return cache.addAll([
'/index.html',
'/styles.css',
'/script.js'
]);
})
);
});3. 激活(Activation)
安装完成后,Service Worker 进入激活阶段,触发 activate 事件。在这个阶段,开发者可以清理旧的缓存资源。
// www.javascriptcn.com code example
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.filter(cacheName => {
return cacheName !== 'v1';
}).map(cacheName => {
return caches.delete(cacheName);
})
);
})
);
});4. 等待(Waiting)
如果已经有其他 Service Worker 在控制页面,新的 Service Worker 会进入等待状态,直到所有客户端都关闭或手动跳过等待。
self.addEventListener('install', event => {
self.skipWaiting();
});5. 控制(Control)
一旦激活成功,Service Worker 将控制页面,并开始拦截网络请求。
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});6. 终止(Termination)
当不再需要时,Service Worker 会被浏览器终止以节省资源。开发者可以通过 self.clients.claim() 方法立即控制所有客户端。
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim());
});