第九章 保持数据同步

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

9.1 理解后台同步

9.1.1 准备开始

注册后台同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

响应同步事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 提供备用方案

1
2
3
4
5
if ('serviceWorker' in navigator && 'SyncManager' in window) {
// ...
} else {
// ...
}

9.3 定期同步

1
2
3
4
5
6
7
8
9
10
11
12
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:设备连接到蜂窝网络时推迟同步。