JackAtlas

Command Palette

Search for a command to run...

第九章 保持数据同步 - 《Progressive Web Apps》读书笔记九
about 7 years ago
前端开发

第九章 保持数据同步 - 《Progressive Web Apps》读书笔记九

BackgroundSync API 允许用户在离线工作时对需要发送到服务器的数据进行排队,一旦用户再次上线,会将排队中的数据发送给服务器。

9.1 理解后台同步

9.1.1 准备开始

注册后台同步

if ('serviceWorker' in navigator && 'SyncManager' in window) {
  navigator.serviceWorker.register('./sw.js')
    .then(registration => navigator.serviceWorker.ready)
    .then(registration => {
      document.getElementById('submit').addEventListener('click', () => { // 为id为submit的按钮添加单击事件监听器
        registration.sync.register('contact-email')
          .then(() => { // 为该事件注册同步并使用contact-email作为标签名
            var payload = {
              name: document.getElementById('name').value,
              email: document.getElementById('email').value,
              subject: document.getElementById('subject').value,
              message: document.getElementById('message').value
            }
            idbKeyval.set('sendMessage', payload) // 从页面中取得payload数据并将其保存到IndexedDB中
          })
      })
    })
}
注:idb-keyval 库是一个 IndexedDB 库。

9.1.2 Service Worker

响应同步事件

importScripts('./js/idb-keyval.js')
self.addEventListener('sync', event => { // 为同步事件添加事件监听器
  if (event.tag === 'contact-email') { // 检查当前同步的标签名,以确保出发的是正确的代码
    event.waitUntil(
      idbKeyval.get('sendMessaage').then(value => { // 从IndexedDB中获取有效载荷值
        fetch('/sendMessaage/', { // 使用fetchAPI向服务器发起POST请求
          method: 'POST',
          headers: new Headers({'content-type': 'application/json'}),
          body: JSON.stringify(value) // 将从IndexedDB中获取的有效载荷值作为参数传递给服务器
        }).then(response => {
          if (response.status >= 200 && response.status < 300) {
            idbKeyval.delete('sendMessaage') // 从IndexedDB中移除有效载荷值
          }
        })
      })
    )
  }
})

9.1.3 提供备用方案

if ('serviceWorker' in navigator && 'SyncManager' in window) {
  // ...
} else {
  // ...
}

9.3 定期同步

navigator.serviceWorker.ready.then(function (registration) {
  registration.periodicSync.register({
    tag: 'get-latest-news', // 同步事件的标签名
    minPeriod: 12 * 60 * 60 * 1000, // 两次成功的同步事件之间的最小时间间隔
    powerState: 'avoid-draining', // 确定同步的电池需求。可设置为'auto'或'avoid-draining'
    networkState: 'avoid-cellular' // 确定同步的网络需求。可以设置为'online'(默认)、'avoid-cellular'或'any'
  }).then(function (periodicSyncReg) {
    // 成功
  }, function () {
    // 失败
  })
})

powerState:

  • auto:允许在电池消耗过程中进行同步,但如果设备启用了省电模式,则可能会受到限制。
  • avoid-draining:电池未充电时,推迟电池供电的设备的同步。

networkState:

  • avoid-cellular:设备连接到蜂窝网络时推迟同步。 许可协议