有時服務作業者 (SW) 的注冊會掛起。由于我們的 PWA 依賴于 SW,沒有它就無法啟動,看起來我們的應用程式在啟動時掛起。看來我需要撰寫一個逃生艙口。我尋求建議。
注冊掛起的事實是通過插入 90 秒超時來建立的,如下所示。
const serviceWorker = navigator.serviceWorker;
if( serviceWorker && typeof serviceWorker.register === 'function' ) {
swRegisterTimeout = setTimeout(swRegTimedOut,90000);
serviceWorker.register('serviceworker.js')
.then(onServiceworkerRegistered)
.catch(function(err){
clearTimeout(swRegisterTimeout);
message("Service Worker Register Failure");
})
} else {
if ( serviceWorker ) {
message("'serviceWorker.register' is not a function")
}else{
message("'navigator.serviceWorker' does not exist")
}
}
});
function swRegTimedOut(){
message("ServiceWorker unable to register in 90 seconds")
}
function onServiceworkerRegistered(){
var serviceWorker = navigator.serviceWorker,
postBox = serviceWorker.controller;
clearTimeout(swRegisterTimeout);
message("Service Worker Registered");
serviceWorker.ready.then(function(reg){
if(reg.active){
// More stuff
}
})
}
這種情況只有在我們的互聯網可以運行時才會發生,但幾乎沒有。然后我每次都遇到問題 - 九十秒后出現超時訊息,并且應用程式無法啟動。
如果沒有互聯網,就不會掛起;一切立即開始。事實上,我可以通過關閉研發機器上的 Wifi 來解決這個問題。繁榮!一切都立即加載。
我推測在注冊代碼的某個地方,正在嘗試 I/O。如果所述 I/O 沒有失敗或成功,則注冊不會回傳。
為了有選擇地繞過注冊步驟,我們的代碼需要能夠識別掛起和有效注冊之間的區別。我們必須在這里小心;我不想寫一些會破壞對其他瀏覽器的支持的東西。
編輯:如果有服務人員,這只是一個問題。不用說,我不希望在一個幾乎死機的網路上加載一個新的 service worker 和初始檔案。
uj5u.com熱心網友回復:
背景
讓我們分解什么navigator.serviceWorker.register(),以及它回傳的承諾代表什么。
最終的步驟集記錄在服務作業者規范中,從“開始注冊”作業開始。根據 service workerscriptURL和scope之前是否注冊過,行為會略有不同,所以首先要問自己的是,您是否僅在第一次注冊時才在“干凈”瀏覽器中看到此內容,或者當存在相同的、預先存在的服務作業者注冊時,您是否也會看到它。
navigator.serviceWorker.register()無論哪種方式,一旦明確注冊是針對具有scope遵循安全限制的有效 JavaScript 的腳本資源,回傳的承諾就會實作。
如果你嘗試注冊一個語法無效的 JavaScript 檔案,或者你使用的檔案與scope服務作業者限制不兼容,或者存在阻止請求 JavaScript 的網路錯誤,則 Promise 將被拒絕。
需要注意的是,navigator.serviceWorker.register()決議的方式并不能反映正在注冊的服務作業者是否實際安裝正確。可以注冊一個不包含任何語法錯誤且具有有效范圍(因此navigator.serviceWorker.register()將實作)的服務作業者腳本,但它會redundant在install階段期間變為,可能是因為它傳遞給的承諾installEvent.waitUntil()最終被拒絕。實作的事實navigator.serviceWorker.register()確實意味著您將始終擁有一個installed服務人員!
獨立于注冊使用 navigator.serviceWorker.ready
因此,讓我們來看看您的特定代碼片段。如果您在navigator.serviceWorker.register()網路連接不穩定時看到長時間延遲后回傳的 promise,則幾乎可以肯定它被拒絕,因為對 service worker 腳本的網路請求最終超時。對于這種情況,你真的無能為力——這就是當你有一個不穩定的網路時發生的事情的定義,為了確保你的服務作業者總是“新鮮的”,服務作業者腳本的請求將默認繞過任何快取.
navigator.serviceWorker.ready不過,我認為您遇到的問題是,一旦有服務作業者,您就使用執行一些代碼,但只有在承諾履行active時才呼叫它。navigator.serviceWorker.register()由于上述原因,我認為您不應該以這種方式構建代碼。
相反,我會將您的代碼分成兩個步驟——一個呼叫navigator.serviceWorker.register(),另一個等待navigator.serviceWorker.ready完成,彼此獨立。
navigator.serviceWorker.register()
.then(() => console.log('Registration succeeded.')
.catch((error) => console.log('Registration failed: ', error));
navigator.serviceWorker.ready.then(() => {
// Put whatever code requires an active service worker here.
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/434645.html
標籤:javascript 谷歌浏览器 服务人员
上一篇:嘗試訪問API時如何修復錯誤?
下一篇:快速閱讀plist并處理錯誤
