服务工作者同步仅在第一次触发

时间:2017-01-23 17:02:38

标签: service-worker background-sync

点击按钮,我成功注册了sync,它激发了我在service-worker中描述的功能。 如果我处于离线状态 - 它等待浏览器获得连接然后触发它。

但是 - 当我第一次单击按钮并且一切正常时 - 再次单击该按钮会成功注册sync,但是service-worker中的sync事件永远不会触发:

self.addEventListener('sync', function(event) {
    console.log('EVENT in SYNC', event);
}

我看到控制台仅在我第一次点击按钮时记录。 我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

我想出来了:) ...问题非常严重:服务工作者中的sync处理程序正在返回一个承诺,但这个承诺从未得到解决。一旦我在处理程序返回的promise中添加了resolve()部分 - 一切正常。

PS:在Jake Archibald的演示中,sync处理程序正在执行self.registration.showNotification,它返回一个promise,一旦显示通知,此promise就会解析。在其他示例中,他们制作简单的fetch,这也会返回承诺,并且该承诺会在成功时解决。但就我的例子而言 - 我从indexedDB提取数据然后制作fetch。 所以 - 只需将所有内容包装在

var p = new Promise(function(resolve, reject) {
    // get data from indexedDB .. 
    fetch(...).then(function(response) {
        return response;
    })
    .then(function() {
        // fetch was successful .. 
        resolve();
    });
};
return p;

这种方式可以正常工作。

答案 1 :(得分:0)

这些API的实验性很强,很可能会更改,因此请不要相信我。我没有任何文档可以支持我的经验。

就我而言,“同步”事件仅设计触发一次。因此,在使每个必须发送请求入队后,我通过注册SyncManager使其达到了预期的工作:

self.addEventListener('fetch', evt=> {
  if(isSuperImportant(evt.request)) {
    evt.respondWith(Promise.resolve(new Response({status: 201})));
    evt.waitUntil(
      myEnqueue(evt.request).then(()=> {
        return self.registration.sync.register('sync-tag'); 
      })
    );
  }
  else {
    // process the non-important requests
  }
});


self.addEventListener('sync', evt=> {
  evt.waitUntil(tryToFlushMyQueue());
});