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:设备连接到蜂窝网络时推迟同步。 许可协议



![[译] 终于,JavaScript 有了安全的数组方法](https://img-1252058122.cos.ap-guangzhou.myqcloud.com/blog/article-cover/cmfkkq9a00001uhcg5k63cmt3.jpg)

