3

是否有可能讓服務人員等待開始處理提取事件,直到服務工作人員啓動時完成異步工作?是否有Service Worker啓動waitUntil來延遲處理提取?

我有一個應用程序外殼與數據中定義的路線。要在服務人員啓動時安裝特定的路由獲取處理程序,我需要從IndexedDB查找路由數據(異步)。

不幸的是,在IndexedDB查找可以完成並設置路由的提取處理之前,服務工作者開始接受提取事件。

現在,我只是硬編碼一個特殊情況下的默認處理程序,但如果讓服務工作人員延遲處理提取事件,直到服務工作人員啓動時IndexedDB處理完成爲止,那就太好了。

我沒有看到「waitUntil」的方法,也許我錯過了它?

回答

3

有一種變通方法:

function startupAsyncStuff() { 
    return new Promise(function (fulfill, reject) { 
    // put here your async stuff and fulfill the promise when done. 
    }); 
} 

// Launch your startup async code 
var asyncStuffDone = startupAsyncStuff(); 

// On fetch, wait for the former promise to be resolved first 
self.onfetch = function (event) { 
    event.respondWith(asyncStuffDone.then(function() { 
    // your fetch handling code 
    })); 
}; 
+0

這是一個很好的一般情況下的正確答案。謝謝! –

+0

對不起,這個承諾驅動的代碼對我來說仍然是新的。你如何「完成承諾」?什麼是「拒絕」參數。感謝您對我的noob問題的耐心(: –

6

的代碼段,將有助於爲我不是100%在這個問題上明確......但要做出一些猜測:

直到你解決提供給event.waitUntil當你聽了安裝活動的承諾,軟件不應攔截任何網絡請求,因此在那裏設置的IDB應該沒問題。

一般來說,只要讓fetch事件偵聽器運行並且不做任何事情也沒有問題,因爲瀏覽器將在正常情況下回退到網絡。

一般來說,也值得一提的是,SW可以並且經常被殺死,因此局部變量不會在接收不同事件之間停留。如果處理其他事件時需要某些數據,則應將其保存在IDB或緩存API中,然後再從該處讀取。

+0

Event.waitUntil在哪裏啓動?我的情況發生在SW被殺後重新開始爲頁面提供服務。 –

+1

啊,我假設問題是安裝後等待,不是每次啓動。如果問題在於您需要在啓動後執行IDB查找,但在路由獲取的抓取之前,您應該能夠在抓取偵聽器中調用e.waitUntil並傳回一個承諾,該承諾將在生成反應,其中一部分將涉及IDB查詢。讓我知道如果我仍然是誤解,高興地看看代碼片段:) – owencm

+0

你已經明白了 - 這是關鍵。看起來解決方案是爲這個和waitUntil添加一個提取處理程序。我沒有這個「片段」,但是勇敢/好奇的人可以看到[code](https://github.com/localnerve/flux-react-example-sw/tree/master/assets/scripts/) SW)。這兩個問題** 1。**在啓動時,sw進程尚未運行時出現「脫機dino」閃存,[參考](http://stackoverflow.com/questions/33906701/what-is-the-expected -startup-experience-for-a-progressive-web-application)** 2。**在不必要的未捕捉獲取通過網絡的情況下, –

0

由於我使用SW-工具箱並在啓動時執行異步的工作,設定路線的處理程序,對我來說最好的解決辦法是定義一個臨時SW-工具箱默認處理程序直到處理程序準備響應。

var toolbox = require('sw-toolbox'); 

var setupPromise = someAsyncHandlerSetup() 
.then(function() { 
    // make default handler temporary, allows other fetch handlers. 
    toolbox.router.default = null; 
}); 

// until the async handler setup is done, provide a default handler 
// to avoid an offline-dino flash when starting up while offline. 
toolbox.router.default = function defaultHandler (request) { 
    return setupPromise.then(function() { 
    var handler = toolbox.router.match(request); 
    if (handler) { 
     return handler(request); 
    } 
    throw new Error('default handler could not handle ' + request.url); 
    }); 
};