6

Tôi đang sử dụng ServiceWorker để triển khai thông báo của người dùng. Khi người sử dụng lần đầu truy cập trang web và phê duyệt thông báo, ServiceWorker được đăng ký và đăng ký:Đợi ServiceWorker hoàn tất đăng ký trước khi đăng ký

if ('serviceWorker' in navigator) { 
console.log('Service Worker is supported'); 
navigator.serviceWorker.register('/js/sw.js').then(function(reg) { 
    if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){ 
     reg.pushManager.subscribe({ 
      userVisibleOnly: true 
     }).then(function(sub) { 
      console.log('endpoint:', sub.endpoint); 
      endpoint = sub.endpoint; 
      fetch(MY_API+encodeURIComponent(endpoint), { 
        credentials: 'include' 
       }) 
     }); 
    } 
}).catch(function(err) { 
    console.log(':^(', err); 
}); 
} 

Trên chuyến viếng thăm đầu tiên, điều này failes với:

Uncaught (in promise) DOMException: Subscription failed - no active Service Worker 

Từ lần thứ hai trở đi, mọi thứ đều OK vì ServiceWorker đã hoạt động tại thời điểm đó. Có vẻ như đây là vấn đề về thời gian. Làm thế nào tôi có thể chắc chắn ServiceWorker đã được đăng ký thành công và hoạt động trước khi tôi cố gắng đăng ký nó?

tôi đã cố gắng sử dụng navigator.serviceWorker.ready như đề xuất dưới đây:

if ('serviceWorker' in navigator) { 
console.log('Service Worker is supported'); 
navigator.serviceWorker.register('/js/sw.js').then(function(sreg) { 
    console.log(':^)', sreg); 
    navigator.serviceWorker.ready.then(function(reg) { 
     if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){ 
      reg.pushManager.subscribe({ 
       userVisibleOnly: true 
      }).then(function(sub) { 
       console.log('endpoint:', sub.endpoint); 
       endpoint = sub.endpoint; 
       fetch("https://www.wettfreun.de/?page=fetch&s=1&endpoint="+encodeURIComponent(endpoint), {credentials: 'include'}) 
      }); 
     } 
    }); 
}).catch(function(err) { 
    console.log(':^(', err); 
}); 
} 

Bây giờ là phần bên trong navigator.serviceWorker.ready.then() không bao giờ được gọi.

+0

Tại sao bạn đang sử dụng Push API chỉ trên Chrome/Chromium? – Marco

+0

Vì chương trình phụ trợ của tôi hiện chỉ hỗ trợ GCM – Hokascha

+0

Nếu không có tải trọng, tiêu chuẩn Đẩy Web thực sự đơn giản để triển khai (về cơ bản là yêu cầu POST tới URL điểm cuối). – Marco

Trả lời

5

Bạn có thể sử dụng ServiceWorkerContainer.ready.

Ví dụ từ MDN:

function subscribe() { 
    var subscribeButton = document.querySelector('.js-subscribe-button'); 
    subscribeButton.disabled = false; 

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { 
    serviceWorkerRegistration.pushManager.subscribe() 
     .then(function(subscription) { 
     // The subscription was successful 
     subscribeButton.disabled = true; 
     return sendSubscriptionToServer(subscription); 
     }) 
     .catch(function(error) { 
     if (Notification.permission === 'denied') { 
      console.log('Permission for Notifications was denied'); 
      subscribeButton.disabled = true; 
     } else { 
      console.log('Unable to subscribe to push.', error); 
      subscribeButton.disabled = false; 
     } 
     }); 
    }); 
} 
+0

Bạn có thể trình bày một ví dụ không? Không có đăng ký trong tài liệu bạn đã cung cấp. Cuộc gọi sẵn sàng() nên được thực hiện ở đâu? – Hokascha

+0

Tôi đã thêm một ví dụ từ MDN. – Marco

+0

Ah, có thể bạn cũng muốn biết cách làm cho nhân viên dịch vụ hoạt động trong lần đầu tiên bạn tải trang? Xem https://serviceworke.rs/immediate-claim.html. – Marco