1

单击按钮时,我成功注册sync,它会触发我在service-worker. 如果我离线 - 它会等待浏览器获得连接然后触发。

但是 - 当我第一次单击按钮时一切都很好 - 从那时起再次单击按钮成功注册sync,但sync服务工作者中的事件永远不会触发:

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

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

4

2 回答 2

2

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

PS:在 Jake Archibald 的演示中,sync处理程序正在执行self.registration.showNotification,它返回一个承诺,一旦显示通知,这个承诺就会解决。在其他示例中,他们使 simple fetch,它也返回 promise,并且该 promise 在成功时解决。但在我的例子中 - 我正在从中提取数据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;

这样它就可以正常工作。

于 2017-01-26T18:39:34.600 回答
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());
});
于 2018-12-04T00:18:26.197 回答