概述离线队列可保障关键事件不丢失。本文提供队列持久化与回放示例。队列与回放function openDB(name) { return new Promise((resolve, reject) => { const r = indexedDB.open(name, 1); r.onupgradeneeded = () => { const db = r.result; if (!db.objectStoreNames.contains('events')) db.createObjectStore('events', { autoIncrement: true }); }; r.onsuccess = () => resolve(r.result); r.onerror = () => reject(r.error); }); } async function enqueueEvent(evt) { const db = await openDB('evt'); const tx = db.transaction('events','readwrite'); tx.objectStore('events').add(evt); await new Promise((res, rej) => { tx.oncomplete = res; tx.onerror = () => rej(tx.error); }); db.close(); } self.addEventListener('fetch', event => { if (event.request.method === 'POST') { event.respondWith(fetch(event.request).catch(async () => { await enqueueEvent({ url: event.request.url, body: await event.request.clone().text() }); return new Response('', { status: 202 }); })); } }); self.addEventListener('sync', e => { if (e.tag === 'replay-events') { e.waitUntil((async () => { const db = await openDB('evt'); const tx = db.transaction('events','readwrite'); const s = tx.objectStore('events'); const req = s.openCursor(); await new Promise((res, rej) => { req.onsuccess = async ev => { const c = ev.target.result; if (c) { try { await fetch(c.value.url, { method:'POST', body: c.value.body }); s.delete(c.primaryKey); c.continue(); } catch { res(); } } else res(); }; req.onerror = () => rej(req.error); }); await new Promise((res, rej) => { tx.oncomplete = res; tx.onerror = () => rej(tx.error); }); db.close(); })()); } });

发表评论 取消回复