Service Worker 同步仅在第一次触发

Service worker sync fires only the first time

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

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

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

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

我想通了 :) ... 问题很蹩脚:service worker 中的 sync 处理程序正在返回一个承诺,但这个承诺从未得到解决。一旦我在处理程序中添加了 resolve() 部分返回承诺 - 它一切正常。

PS:在 Jake Archibald 的演示中,sync 处理程序正在执行 self.registration.showNotification,这是一个 returns 承诺,一旦显示通知,该承诺就会解决。在其他示例中,他们制作了简单的 fetch,这也是 returns 承诺,并且该承诺会在成功时解决。但在我的示例中——我从 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;

这样就可以正常工作了。

这些 API 是非常实验性的,它们很可能会改变,所以不要相信我的话。我没有任何文档来支持我的经验。

在我的例子中,'sync' 事件按设计只触发一次。所以我通过在每个 must-send 请求排队后注册到 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());
});