2016-02-29 64 views
2

ServiceWorkerContainer.ready解析爲活動的ServiceWorkerRegistration,但如果存在多個服務工作人員(例如,來自上一頁加載的服務工作人員,同一頁面內的多個註冊人員),則可以解析爲多個服務工作人員。如何確保特定的服務人員在執行大量代碼時處理網絡事件?ServiceWorkerContainer.ready是否適用於特定的scriptURL?

也就是說,我怎麼可以編寫一個函數registerReady(scriptURL, options),可以使用如下:

registerReady("foo.js").then(function (r) { 
    // "foo.js" is active and r.active === navigator.serviceWorker.controller 
    fetch("/"); // uses foo.js's "fetch" handler 
}); 

registerReady("bar.js").then(function (r) { 
    // "bar.js" is active and r.active === navigator.serviceWorker.controller 
    fetch("/"); // use bar.js's "fetch" handler 
}); 

回答

2

首先,注意有可按每範圍只有一個活動的服務工作人員和您的客戶端頁面可以通過控制最多也是唯一一名服務人員。因此,當準備好解決時,您肯定知道控制您的頁面的服務工作人員處於活動狀態。

要知道任意sw是否處於活動狀態,您可以註冊並檢查註冊中的服務工作人員隊列,並監聽其狀態變化。例如:

function registerReady(swScript, options) { 
    return navigator.serviceWorker.register(swScript, options) 
    .then(reg => { 
    // If there is an active worker and nothing incoming, we are done. 
    var incomingSw = reg.installing || reg.waiting; 
    if (reg.active && !incomingSw) { 
     return Promise.resolve(); 
    } 

    // If not, wait for the newest service worker to become activated. 
    return new Promise(fulfill => { 
     incomingSw.onstatechange = evt => { 
     if (evt.target.state === 'activated') { 
      incomingSw.onstatechange = null; 
      return fulfill(); 
     } 
     }; 
    }); 
    }) 
} 

希望它對你有意義。

+0

我發現還有[提案](https://github.com/slightlyoff/ServiceWorker/issues/770)添加類似於服務工作者規範的東西。 – mjs

+0

我認爲這不太正確:在'activated'塊中,還需要檢查e.target === navigator.serviceWorker.controller:在加載服務工作者的第一頁上將變爲活動狀態(在它已經準備好從* some *頁面接收函數事件了),但它實際上不會控制註冊它的頁面,除非它調用clients.claim()。 – mjs