refactor(useTalkRecord): 简化消息比较逻辑,改为全量检查
根据用户建议,只比较msg_id和is_revoke字段,并改为全量检查所有消息。因为消息ID是唯一的,且一次只有30条消息,全量检查不会带来太大性能负担。
This commit is contained in:
parent
0b8de6f5c2
commit
c3abd733ad
@ -224,91 +224,38 @@ export const useTalkRecord = (uid: number) => {
|
|||||||
|
|
||||||
// 如果首尾消息ID存在于服务器数据中,进行详细比较
|
// 如果首尾消息ID存在于服务器数据中,进行详细比较
|
||||||
if (firstServerIdx !== undefined && lastServerIdx !== undefined) {
|
if (firstServerIdx !== undefined && lastServerIdx !== undefined) {
|
||||||
const criticalFields = ['is_revoke', 'is_read', 'is_mark']
|
// 根据用户建议,只比较msg_id和is_revoke字段
|
||||||
|
// 因为消息ID是唯一的,内容变化主要是由撤回操作引起的
|
||||||
// 比较首尾消息的关键字段
|
|
||||||
const compareMessage = (localMsg, serverMsg) => {
|
const compareMessage = (localMsg, serverMsg) => {
|
||||||
// 比较基本字段
|
// 消息ID已在外部比较过,这里只需检查is_revoke状态
|
||||||
for (const field of criticalFields) {
|
return localMsg.is_revoke === serverMsg.is_revoke
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const firstMatch = compareMessage(firstLocalMsg, items[firstServerIdx])
|
const firstMatch = compareMessage(firstLocalMsg, items[firstServerIdx])
|
||||||
const lastMatch = compareMessage(lastLocalMsg, items[lastServerIdx])
|
const lastMatch = compareMessage(lastLocalMsg, items[lastServerIdx])
|
||||||
|
|
||||||
// 如果首尾消息匹配,使用抽样检查中间消息
|
// 如果首尾消息匹配,进行全量检查所有消息
|
||||||
if (firstMatch && lastMatch) {
|
if (firstMatch && lastMatch) {
|
||||||
// 智能抽样检查策略
|
// 全量检查策略:检查所有消息
|
||||||
// 1. 检查首尾消息(已完成)
|
// 由于一次只有30条消息,全量检查不会带来太大的性能负担
|
||||||
// 2. 检查中间点消息
|
|
||||||
// 3. 检查最近修改的消息(通常是最新的几条)
|
|
||||||
// 4. 随机抽样检查
|
|
||||||
|
|
||||||
let allMatch = true
|
let allMatch = true
|
||||||
|
|
||||||
// 中间点检查
|
// 遍历所有本地消息,与服务器消息进行比较
|
||||||
const midIndex = Math.floor(localMessages.length / 2)
|
for (let i = 0; i < localMessages.length; i++) {
|
||||||
const midMsg = localMessages[midIndex]
|
const localMsg = localMessages[i]
|
||||||
const midServerIdx = serverMsgMap.get(midMsg.msg_id)
|
const serverIdx = serverMsgMap.get(localMsg.msg_id)
|
||||||
|
|
||||||
if (midServerIdx === undefined || !compareMessage(midMsg, items[midServerIdx])) {
|
// 如果消息ID不存在于服务器数据中,或者消息内容不匹配
|
||||||
|
if (serverIdx === undefined || !compareMessage(localMsg, items[serverIdx])) {
|
||||||
allMatch = false
|
allMatch = false
|
||||||
}
|
console.log(`消息不匹配,索引: ${i}, 消息ID: ${localMsg.msg_id}`)
|
||||||
|
break // 一旦发现不匹配,立即退出循环
|
||||||
// 最近消息检查(检查最新的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 < 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allMatch) {
|
if (allMatch) {
|
||||||
const compareEndTime = performance.now()
|
const compareEndTime = performance.now()
|
||||||
console.log(`本地数据与服务器数据一致(抽样检查),无需更新UI,比较耗时: ${(compareEndTime - compareStartTime).toFixed(2)}ms`)
|
console.log(`本地数据与服务器数据一致(全量检查),无需更新UI,比较耗时: ${(compareEndTime - compareStartTime).toFixed(2)}ms`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user