2016-04-09 70 views
0

不知道我在做什麼我的服務工作者實施錯誤。Web推送服務偶爾錯誤

理想情況下,我面臨的問題是「網站已在此背景下刷新」。

我之前沒有遇到過這個問題,但是一旦推送通知訂閱人數達到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; 
 
     }); 
 
     }) 
 
); 
 
});

回答

0

這種經常發生的原因是承諾返回event.waitUntil()沒有與被顯示的通知解決。

可能會顯示默認的「網站已在後臺刷新」的例子通知:

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的承諾來解決/完成,以便他們知道服務工作人員需要保持活動並運行。

當承諾解決了推送事件時,chrome將檢查通知是否已顯示,並且它會落入競爭條件/特定情況,以確定Chrome是否顯示此通知。最好的辦法是確保你有一個正確的承諾鏈。

我在這篇文章上寫了一些關於承諾的額外註釋(參見:'支付任務:承諾'https://gauntface.com/blog/2016/05/01/push-debugging-analytics