簡體   English   中英

如何在 Service Worker 安裝事件中處理被拒絕的 Promise?

[英]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 就會完成,無論安裝是否失敗(甚至可能不再需要安裝)。 要檢查安裝是否失敗,您需要監聽正在安裝的 workerstatechange事件

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM