Files
wxserver/utils/sync.js
T
yuming 1142346e24 新增前端订阅模块,收敛模板 ID 到唯一来源
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 09:25:12 +08:00

69 lines
2.0 KiB
JavaScript

/**
* 同步管理:失败入队,启动时重试
* Why:自建后端、HTTPS 链路、定时任务任一环节抖动都会导致单次写入丢失。本地队列兜底,保证最终一致。
*/
const api = require('./api')
const QUEUE_KEY = 'pending_sync_queue'
function loadQueue() {
try { return wx.getStorageSync(QUEUE_KEY) || [] } catch (e) { return [] }
}
function saveQueue(q) {
try { wx.setStorageSync(QUEUE_KEY, q) } catch (e) {}
}
function enqueue(item) {
const q = loadQueue()
q.push({ ...item, ts: Date.now() })
saveQueue(q)
}
async function dispatch(item) {
if (item.kind === 'person') return api.person(item.action, item.data)
if (item.kind === 'anniversary') return api.anniversary(item.action, item.data)
if (item.kind === 'subscribe') return api.subscribe(item.action, item.data)
throw new Error('unknown sync kind: ' + item.kind)
}
// 立即尝试同步;失败入队
async function syncOrEnqueue(item) {
try {
const res = await dispatch(item)
if (res && res.success === false) throw new Error(res.error || 'server returned failure')
return true
} catch (err) {
console.warn('[sync] 失败已入队:', item.kind, item.action, err.message || err)
enqueue(item)
return false
}
}
// 尝试 flush 整个队列,失败的留下下次再试
async function flush() {
const q = loadQueue()
if (q.length === 0) return { flushed: 0, remaining: 0 }
const remaining = []
let flushed = 0
for (const item of q) {
try {
const res = await dispatch(item)
if (res && res.success === false) throw new Error(res.error || 'server returned failure')
flushed++
} catch (err) {
remaining.push(item)
}
}
saveQueue(remaining)
if (flushed > 0) console.log(`[sync] 队列 flush 完成:成功 ${flushed},剩余 ${remaining.length}`)
return { flushed, remaining: remaining.length }
}
function getPendingCount() {
return loadQueue().length
}
module.exports = { syncOrEnqueue, flush, getPendingCount }