Якщо вам доводилося працювати з Service Workers, ви могли зіткнутися з певними проблемами пов'язаними з тим, що попередній Service Worker досі контролюється документом, навіть за умови, що сам файл був оновлений. Причиною цього може бути специфіка організації діяльності Service Workers; вони можуть бути встановлені і дійсні, проте все ж не контролюватися документом.
Service Worker може перебувати в одному з шести станів – parsed (оброблено), installing (установка), installed (встановлено), activating (активація), activated (активовано), і redundant (зайвий).
Parsed
Коли ми вперше спробуємо зареєструвати Service Worker, агент користувача обробляє сценарій і отримує точку входу. Якщо обробка успішна (і деякі інші вимоги, наприклад, HTTPS, будуть виконані), ми матимемо доступ до реєстраційного об'єкта Service Worker. Він містить інформацію про стан Service Worker, а також його обсяг.
/* In main.js */
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
.then(function(registration) {
console.log("Service Worker Registered", registration);
})
.catch(function(err) {
console.log("Service Worker Failed to Register", err);
})
}
Успішна реєстрація Service Worker не означає, що він вже встановлений або активний, тільки те, що сценарій був успішно проаналізований. Як тільки це буде завершено, Service Worker переходить до наступного стану.
Installing
Після того, як скрипт Service Worker був розібраний, агент користувача намагається встановити його і він переміщається в стан Installing. В Service Worker об'єкті registration, ми можемо перевірити наявність цього стану в дочірньому об'єкті installing.
/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {
if (registration.installing) {
// Service Worker встановлюється
}
})
Під час стану встановлення, install подія в Service Worker завершується. У типовій події install, ми кешуємо статичні файли для документа.
/* In sw.js */
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(currentCacheName).then(function(cache) {
return cache.addAll(arrayOfFilesToCache);
})
);
});
Якщо в події є метод event.waitUntil()
, установка не буде успішною, поки Promise в ньому не буде вирішений. Якщо Promise відхилено, установка припиняється і Service Worker стає зайвим.
/* In sw.js */
self.addEventListener('install', function(event) {
event.waitUntil(
return Promise.reject(); // Failure
);
});
Подія установки перервана.
Installed / Waiting
Якщо установка пройшла успішно, Service Worker переходить до стану встановлено (або очікування). У цьому стані він дійсний, але ще не активний. Він ще не під контролем документу, а швидше очікує, щоб взяти контроль від поточного воркеру. В об'єкті registration, ми можемо перевірити наявність цього стану в дочірньому об'єкті waiting.
/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {
if (registration.waiting) {
// Service Worker у стані очікування
}
})
Це може бути гарний час, щоб повідомити користувачів додатку, що вони можуть оновити його до нової версії, або провести автоматичне оновлення.
Activating
Стан активації буде спрацьовувати для очікуючого Service Worker в одному з наступні сценаріїв -
-
Якщо немає вже активних, поточних воркерів.
-
Якщо метод
self.skipWaiting ()
викликається в сценарії Service Worker -
Якщо користувач вже переходив зі сторінки, тим самим звільняючи попередній активний воркер.
-
Якщо заданий період часу пройшов, тим самим звільняючи попередній активний воркер.
Під час активуючого стану, подія activate в сценарії Service Worker завершується. У типовому випадку активації ми очищаємо файли зі старого кешу.
/* In sw.js */
self.addEventListener('activate', function(event) {
event.waitUntil(
// отримати всі імена кешу
caches.keys().then(function(cacheNames) {
return Promise.all(
// Отримати всі пункти які зберігаються під різними іменами кешу
cacheNames.filter(function(cacheName) {
return cacheName != currentCacheName;
}).map(function(cacheName) {
// Видалити ці пункти
return caches.delete(cacheName);
})
); // завершення Promise.all()
}) // завершення caches.keys()
); // завершення event.waitUntil()
});
Аналогічно до установки, якщо в активації є метод event.waitUntil()
, активація не буде успішною, поки Promise не буде вирішено. Якщо Promise відхилено, активація не відбувається і Service Worker стає зайвим.
Activated
У разі успішної активації, Service Worker переходить в активний стан. У цьому стані, він є активним воркером повністю під контролем документа. У об'єкті registration, ми можемо перевірити цей стан в дочірньому об'єкті active.
/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {
if (registration.active) {
// Service Worker активовано
}
})
Коли Service Worker активний, він тепер може обробляти функціональні події – fetch, і message.
/* In sw.js */
self.addEventListener('fetch', function(event) {
// Виконати з вибірки подій
});
self.addEventListener('message', function(event) {
// Виконати з postMessages отриманих з документу
});
Redundant
Service Worker може стати зайвим за однієї з наступних причин:
-
Якщо установка завершилася невдало
-
Якщо активація завершилася невдало
-
Якщо новий Service Worker замінює його в якості активного service worker
-
Якщо Service Worker є зайвим по одній з перших двох причин, ми можемо побачити його (і пов'язану з ним інформацію) в наших Dev Tools
Якщо він був раніше активний, то зберігає контроль документу.
Ще немає коментарів