在网络不稳定或者断网的场景下,PWA 应用需要保证数据的同步,这时候可以通过 Background Sync 技术来实现。本文将介绍 PWA 应用如何实现 Background Sync,并给出具体的实现步骤和示例代码。
什么是 Background Sync?
Background Sync 是指在网络不稳定或者断网的情况下,PWA 应用可以将用户的操作记录下来,并在网络恢复后进行同步。它可以提供更好的用户体验,并且避免了数据丢失。
举个例子,如果用户在断网情况下提交了一篇文章,这时候 Background Sync 就会将该文章记录下来,在网络恢复后可以将文章同步到服务器,避免了数据的丢失。
如何实现 Background Sync?
实现 Background Sync 的主要步骤包括以下几个方面:
1. 注册 Service Worker
为了使用 Background Sync 技术,首先需要注册 Service Worker。在 Service Worker 中可以监听浏览器的网络状态,并在断网的情况下记录用户的操作。
navigator.serviceWorker .register('sw.js') .then((registration) => { console.log('Service worker registered:', registration); }) .catch((error) => { console.error('Error registering service worker:', error); });
2. 监听网络状态
在 Service Worker 中可以监听网络状态,当网络恢复时可以将之前记录的操作同步到服务器,并更新本地数据。网络状态可以通过 navigator.onLine 属性获取。
// javascriptcn.com 代码示例 self.addEventListener('fetch', (event) => { if (!event.request.url.startsWith('http://localhost:3000/api/post')) { return; } if (event.request.method !== 'POST') { return; } event.respondWith(fetch(event.request)); event.waitUntil( (async function () { try { await fetch(event.request.clone()); } catch (e) { const id = new URLSearchParams(event.request.body).get('id'); const data = JSON.parse(localStorage.getItem('offline-data')); if (data[id]) { data[id] = { ...data[id], status: 'failed', }; } else { data[id] = { id, title: new URLSearchParams(event.request.body).get('title'), content: new URLSearchParams(event.request.body).get('content'), status: 'failed', }; } localStorage.setItem('offline-data', JSON.stringify(data)); } })() ); });
3. 记录用户操作
在 Service Worker 中可以记录用户的操作,包括新建文章、评论等。记录的操作可以保存在本地存储中。
// javascriptcn.com 代码示例 const postData = async (url = '', data = {}) => { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams(data), }); return response.json(); }; const createPost = async (title, content) => { const response = await postData('/api/post', { title, content, }); const data = JSON.parse(localStorage.getItem('offline-data')) || {}; const id = response.id; data[id] = { id, title, content, status: 'succeeded', }; localStorage.setItem('offline-data', JSON.stringify(data)); };
4. 同步数据到服务器
当网络恢复时,可以将之前记录的用户操作同步到服务器。这时候可以遍历本地存储中的操作,将其同步到服务器。
// javascriptcn.com 代码示例 self.addEventListener('sync', (event) => { if (event.tag === 'sync-posts') { event.waitUntil( (async function () { const data = JSON.parse(localStorage.getItem('offline-data')); for (const id of Object.keys(data)) { if (data[id].status === 'failed') { await postData('/api/post', { id, title: data[id].title, content: data[id].content, }); data[id].status = 'succeeded'; } } localStorage.setItem('offline-data', JSON.stringify(data)); })() ); } });
5. 注册 Background Sync
最后需要注册 Background Sync,这样在断网的情况下用户的操作就会被记录下来,在网络恢复后会自动将数据同步到服务器。
// javascriptcn.com 代码示例 const registerBackgroundSync = async (tag) => { if ('serviceWorker' in navigator && 'SyncManager' in window) { const registration = await navigator.serviceWorker.ready; registration.sync .register(tag) .then(() => { console.log(`Registered background sync: ${tag}`); }) .catch((error) => { console.error(`Error registering background sync: ${tag}`, error); }); } }; registerBackgroundSync('sync-posts');
总结
本文介绍了 PWA 应用如何实现 Background Sync,关键步骤包括注册 Service Worker、监听网络状态、记录用户操作、同步数据到服务器和注册 Background Sync。通过使用 Background Sync 技术,可以提供更好的用户体验,并且避免了数据的丢失。
完整示例代码:https://github.com/zhuowenli/offline-samples/tree/main/pwa-sync
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654880407d4982a6eb2c30cb