[英]How do I handle a rejected Promise in a Service Worker install event?
我有一個案例,我需要從 Service Worker 安裝事件中捕獲被拒絕的 promise 並顯示錯誤消息。
我設置了一個名為testsw.js
的測試 Service Worker,它會立即拋出一個被拒絕的 promise,如下所示:
console.log("Hello from SW");
self.addEventListener('install', function (evt) {
evt.waitUntil(Promise.reject(new Error("Test")));
})
我正在使用以下代碼注冊 Service Worker:
navigator.serviceWorker.register('/testsw.js')
.then(function (reg) {
console.log("Service worker successfully registered.", reg);
})
.catch(function (err) {
console.error("Service worker failed to register.", err);
})
在這種情況下, catch
function 永遠不會被命中,並且在此控制台中注冊 Service Worker 會導致 output:
testsw.js:1 Hello from SW
testsw.js:3 Uncaught (in promise) Error: Test
at testsw.js:3
(anonymous) @ testsw.js:3
(index):468 Service worker successfully registered. ServiceWorkerRegistration
我已經嘗試將被拒絕的 promise 包裝在 function 中,並在evt.waitUntil()
中調用它,並拋出一個普通的錯誤,沒有任何變化。 Service Worker 還是放到了冗余的 state 里面,挺好的,不過還是要知道安裝失敗了。
我是否誤解了在 Service Worker 安裝中被拒絕的承諾是如何工作的? 即使 promise 被拒絕,注冊中是否有任何錯誤配置會使其始終命中then
塊? 如果做不到這一點, ServiceWorkerRegistration
class 或其他地方是否有什么東西會告訴我們服務工作者無法安裝或更新?
如果它有所作為,這在 Chrome 77 和 Edge 83 中進行了測試,但沒有成功。
一旦加載腳本並注冊了工作程序,注冊 promise 就會完成,無論安裝是否失敗(甚至可能不再需要安裝)。 要檢查安裝是否失敗,您需要監聽正在安裝的 worker的statechange
事件:
navigator.serviceWorker.register('/testsw.js').then(function (reg) {
console.log("Service worker successfully registered.", reg);
if (reg.installing) {
reg.installing.onstatechange = function(e) {
if (e.target.state == 'installed') {
console.log("Service worker successfully installed.");
} else if (e.target.state == 'redundant') {
console.log("Service worker failed to install.");
}
};
}
}).catch(function (err) {
console.error("Service worker failed to register.", err);
});
如果您還想顯示安裝失敗的原因,您似乎必須自己通過處理install
處理程序中的錯誤並將消息傳遞給原始頁面來執行此操作。 也許還可以嘗試收聽安裝工作人員的error
事件。 但是,您可能必須手動觸發這些,因為未處理的 promise 拒絕不會自動捕獲:
console.log("Hello from SW");
self.addEventListener('install', function (evt) {
const installation = Promise.reject(new Error("Test"));
evt.waitUntil(installation);
installation.catch(err => {
self.clients.matchAll({includeUncontrolled: true}).then(clients => {
for (const client of clients)
client.postMessage({type: 'error', message: err.message});
});
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.