Web推送服务偶尔会出现错误

时间:2016-04-09 15:26:29

标签: javascript service-worker

不确定我的服务工作者实施方式出了什么问题。

理想情况下,我遇到的问题是“网站已在后台刷新”。

在使用代码之前我没有遇到这个问题,但是一旦推送通知订阅者数量达到600左右,它就开始引起每一个问题。

var init = { method: 'GET',
             headers: {
                "Content-Type" : "application/javascript"
             },
              mode: 'cors',
              cache: 'no-cache' 
           };
var worker = self;
var the_endpoint = '';

fetch(the_endpoint, init ).then(function(response) {
  return response.json();
}).then(function(data){
  worker.addEventListener('push', function(event) {
    event.waitUntil(
        worker.registration.showNotification(data.title, {
          body                : data.body,
          icon                : data.icon,
          requireInteraction  : true
        })
    );
  });

  if( data.link != '' ) {
    worker.addEventListener('notificationclick', function(event) {
      event.notification.close();
      var url = data.link;
      event.waitUntil(
          clients.matchAll({
            type: 'window'
          })
              .then(function(windowClients) {
                for (var i = 0; i < windowClients.length; i++) {
                  var client = windowClients[i];
                  if (client.url === url && 'focus' in client) {
                    return client.focus();
                  }
                }
                if (clients.openWindow) {
                  return clients.openWindow(url);
                }
              })
      );
    });
  }
});

尝试2没有后台刷新问题,但并不总是有效。

var init = { method: 'GET',
             headers: {
                "Content-Type" : "application/javascript"
             },
              mode: 'cors',
              cache: 'no-cache' 
           };
var worker = self;
var the_endpoint = '';

self.addEventListener('push', function(event) {
  event.waitUntil(
      fetch(the_endpoint, init).then(function (response) {
        return response.json().then(function (data) {

          var response = self.registration.showNotification(data.title, {
            body: data.body,
            icon: data.icon,
            requireInteraction: true
          });

          if (data.link != '') {
            worker.addEventListener('notificationclick', function (event) {
              event.notification.close();
              var url = data.link;
              event.waitUntil(
                  clients.matchAll({
                    type: 'window'
                  }).then(function (windowClients) {
                    for (var i = 0; i < windowClients.length; i++) {
                      var client = windowClients[i];
                      if (client.url === url && 'focus' in client) {
                        return client.focus();
                      }
                    }
                    if (clients.openWindow) {
                      return clients.openWindow(url);
                    }
                  })
              );
            });
          }

          return response;
        });
      })
  );
});

1 个答案:

答案 0 :(得分:0)

这种情况经常发生的原因是event.waitUntil()返回的承诺在显示通知时无法解决。

可能显示默认值的示例&#34;网站已在后台刷新&#34;通知:

function handlePush() {
  // BAD: The fetch's promise isn't returned
  fetch('/some/api')
  .then(function(response) {
    return response.json();
  })
  .then(function(data) {
    // BAD: the showNotification promise isn't returned
    showNotification(data.title, {body: data.body});
  });
}

self.addEventListener(function(event) {
   event.waitUntil(handlePush());
});

相反,您应该将其写为:

function handlePush() {
  // GOOD
  return fetch('/some/api')
  .then(function(response) {
    return response.json();
  })
  .then(function(data) {
    // GOOD
    return showNotification(data.title, {body: data.body});
  });
}

self.addEventListener(function(event) {
   const myNotificationPromise = handlePush();
   event.waitUntil(myNotificationPromise);
});

这一点非常重要的原因是浏览器等待传递给event.waitUntil的promise以解析/完成,因此他们知道服务工作者需要保持活动并运行。

当承诺针对推送事件做出解决时,Chrome会检查是否已显示通知,并且在Chrome是否显示此通知时,它会陷入竞争状态/特定情况。最好的办法是确保您拥有正确的承诺链。

我在这篇文章中添加了一些关于承诺的额外说明(参见:&#39; Side Quest:Promises&#39; https://gauntface.com/blog/2016/05/01/push-debugging-analytics