yink #17
@ -224,91 +224,38 @@ export const useTalkRecord = (uid: number) => {
|
||||
|
||||
// 如果首尾消息ID存在于服务器数据中,进行详细比较
|
||||
if (firstServerIdx !== undefined && lastServerIdx !== undefined) {
|
||||
const criticalFields = ['is_revoke', 'is_read', 'is_mark']
|
||||
|
||||
// 比较首尾消息的关键字段
|
||||
// 根据用户建议,只比较msg_id和is_revoke字段
|
||||
// 因为消息ID是唯一的,内容变化主要是由撤回操作引起的
|
||||
const compareMessage = (localMsg, serverMsg) => {
|
||||
// 比较基本字段
|
||||
for (const field of criticalFields) {
|
||||
if (localMsg[field] !== serverMsg[field]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 特殊处理content字段,它在extra对象中
|
||||
const localContent = localMsg.extra?.content
|
||||
const serverContent = serverMsg.extra?.content
|
||||
|
||||
if (localContent !== serverContent) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
// 消息ID已在外部比较过,这里只需检查is_revoke状态
|
||||
return localMsg.is_revoke === serverMsg.is_revoke
|
||||
}
|
||||
|
||||
const firstMatch = compareMessage(firstLocalMsg, items[firstServerIdx])
|
||||
const lastMatch = compareMessage(lastLocalMsg, items[lastServerIdx])
|
||||
|
||||
// 如果首尾消息匹配,使用抽样检查中间消息
|
||||
// 如果首尾消息匹配,进行全量检查所有消息
|
||||
if (firstMatch && lastMatch) {
|
||||
// 智能抽样检查策略
|
||||
// 1. 检查首尾消息(已完成)
|
||||
// 2. 检查中间点消息
|
||||
// 3. 检查最近修改的消息(通常是最新的几条)
|
||||
// 4. 随机抽样检查
|
||||
|
||||
// 全量检查策略:检查所有消息
|
||||
// 由于一次只有30条消息,全量检查不会带来太大的性能负担
|
||||
let allMatch = true
|
||||
|
||||
// 中间点检查
|
||||
const midIndex = Math.floor(localMessages.length / 2)
|
||||
const midMsg = localMessages[midIndex]
|
||||
const midServerIdx = serverMsgMap.get(midMsg.msg_id)
|
||||
|
||||
if (midServerIdx === undefined || !compareMessage(midMsg, items[midServerIdx])) {
|
||||
allMatch = false
|
||||
}
|
||||
|
||||
// 最近消息检查(检查最新的3条消息,通常是最可能被修改的)
|
||||
if (allMatch && localMessages.length >= 4) {
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
const recentMsg = localMessages[localMessages.length - i]
|
||||
const recentServerIdx = serverMsgMap.get(recentMsg.msg_id)
|
||||
|
||||
if (recentServerIdx === undefined || !compareMessage(recentMsg, items[recentServerIdx])) {
|
||||
allMatch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 随机抽样检查(如果前面的检查都通过)
|
||||
if (allMatch && localMessages.length > 10) {
|
||||
// 随机选择5%的消息或至少2条进行检查
|
||||
const sampleSize = Math.max(2, Math.floor(localMessages.length * 0.05))
|
||||
const usedIndices = new Set([0, midIndex, localMessages.length - 1]) // 避免重复检查已检查的位置
|
||||
// 遍历所有本地消息,与服务器消息进行比较
|
||||
for (let i = 0; i < localMessages.length; i++) {
|
||||
const localMsg = localMessages[i]
|
||||
const serverIdx = serverMsgMap.get(localMsg.msg_id)
|
||||
|
||||
for (let i = 0; i < sampleSize; i++) {
|
||||
// 生成不重复的随机索引
|
||||
let randomIndex
|
||||
do {
|
||||
randomIndex = Math.floor(Math.random() * localMessages.length)
|
||||
} while (usedIndices.has(randomIndex))
|
||||
|
||||
usedIndices.add(randomIndex)
|
||||
|
||||
const randomMsg = localMessages[randomIndex]
|
||||
const randomServerIdx = serverMsgMap.get(randomMsg.msg_id)
|
||||
|
||||
if (randomServerIdx === undefined || !compareMessage(randomMsg, items[randomServerIdx])) {
|
||||
allMatch = false
|
||||
break
|
||||
}
|
||||
// 如果消息ID不存在于服务器数据中,或者消息内容不匹配
|
||||
if (serverIdx === undefined || !compareMessage(localMsg, items[serverIdx])) {
|
||||
allMatch = false
|
||||
console.log(`消息不匹配,索引: ${i}, 消息ID: ${localMsg.msg_id}`)
|
||||
break // 一旦发现不匹配,立即退出循环
|
||||
}
|
||||
}
|
||||
|
||||
if (allMatch) {
|
||||
const compareEndTime = performance.now()
|
||||
console.log(`本地数据与服务器数据一致(抽样检查),无需更新UI,比较耗时: ${(compareEndTime - compareStartTime).toFixed(2)}ms`)
|
||||
console.log(`本地数据与服务器数据一致(全量检查),无需更新UI,比较耗时: ${(compareEndTime - compareStartTime).toFixed(2)}ms`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user