未首次设置ServiceWorkerRegistration.active(Chrome)

时间:2016-04-24 19:46:29

标签: service-worker

在Chrome Mac上。我正在尝试注册ServiceWorker并为其设置变量。当我调用register()并且之前没有安装过服务工作者时," active" property似乎立即设置为null,然后很快就会初始化(异步?)。

var sw = null;
navigator.serviceWorker.register('preview/sw.js', {scope: 'preview/'}).
    then(function(registration) {
        console.dir(registration);
        sw = registration.active;
        if (!sw) {
          console.log('wat');
          console.dir(registration);
        }
    });

换句话说,我第一次安装服务工作者时进入if-block。控制台在两个console.dir()命令中将active属性设置为等于ServiceWorker,但sw变量为null。

刷新页面可以解决问题。有人知道是什么原因引起的吗?

2 个答案:

答案 0 :(得分:4)

对于您所描述的第一次访问,当该承诺结算但是“正在安装”时,注册尚未active,因此注册的installing属性将返回服务工作者。

由于没有服务工作者处于waiting状态,因此它将转换为activating然后active。所以你的注册属性最初不是active,而是在刷新时,它会是。

以下代码将说明:

navigator.serviceWorker.register('/serviceworker.js').then(onRegistration);

function onRegistration(registration) {
  if (registration.waiting) {
    console.log('waiting', registration.waiting);
    registration.waiting.addEventListener('statechange', onStateChange('waiting'));
  }

  if (registration.installing) {
    console.log('installing', registration.installing);
    registration.installing.addEventListener('statechange', onStateChange('installing'));
  }

  if (registration.active) {
    console.log('active', registration.active);
    registration.active.addEventListener('statechange', onStateChange('active'));
  }
}

function onStateChange(from) {
  return function(e) {
    console.log('statechange initial state ', from, 'changed to', e.target.state);
  }
}

首次访问时,console.log输出将为:

installing ServiceWorker {scriptURL: "http://...", state: "installing", onstatechange: null, onerror: null}
statechange initial state installing changed to installed
statechange initial state installing changed to activating
statechange initial state installing changed to activated

状态变化与您观察到的异步发生。

答案 1 :(得分:0)

服务工作者已注册,但尚未处于活动状态,但尚未控制您的网页。

如果您希望服务工作者变为活动状态,可以在install事件处理程序中调用函数skipWaiting

如果您希望服务工作者在页面变为活动状态时立即控制该页面,则可以使用activate事件处理程序中的Clients.claim函数。

您可以在ServiceWorker Cookbook Immediate Claim recipe中看到一个示例。