fix(admin): useTable 请求竞态守卫(旧请求不清 loading/不写错误态)
- fetchData 加请求序号令牌 fetchSeq:请求被新请求取代后,旧响应不再 改动任何状态——修复两类竞态:旧请求取消分支把 loading 提前清成 idle、 旧请求失败分支把新请求在途数据清空并置 error - 与 dashboard reqSeq 修法同口径(id===seq 才写数据/清 loading), 供访客列表等分页筛选页复用 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -197,6 +197,9 @@ function useTableImpl<TApiFn extends (params: any) => Promise<any>>(
|
||||
// 请求取消控制器
|
||||
let abortController: AbortController | null = null
|
||||
|
||||
// 请求序号令牌(竞态守卫):请求被更新的请求取代后,不得再写数据/清 loading/置错误态
|
||||
let fetchSeq = 0
|
||||
|
||||
// 缓存清理定时器
|
||||
let cacheCleanupTimer: NodeJS.Timeout | null = null
|
||||
|
||||
@@ -288,6 +291,7 @@ function useTableImpl<TApiFn extends (params: any) => Promise<any>>(
|
||||
// 创建新的取消控制器
|
||||
const currentController = new AbortController()
|
||||
abortController = currentController
|
||||
const currentSeq = ++fetchSeq
|
||||
|
||||
// 状态机:进入 loading 状态
|
||||
loadingState.value = 'loading'
|
||||
@@ -391,15 +395,24 @@ function useTableImpl<TApiFn extends (params: any) => Promise<any>>(
|
||||
|
||||
return standardResponse
|
||||
} catch (err) {
|
||||
// 竞态守卫:已被更新请求取代的旧请求不再改动任何状态
|
||||
// (防旧 finally 提前清 loading、旧失败响应清空新请求的数据)
|
||||
const superseded = currentSeq !== fetchSeq
|
||||
if (err instanceof Error && err.message === '请求已取消') {
|
||||
// 请求被取消,回到 idle 状态
|
||||
loadingState.value = 'idle'
|
||||
// 请求被取消,回到 idle 状态(仅当它仍是最新请求,如显式 cancelRequest)
|
||||
if (!superseded) loadingState.value = 'idle'
|
||||
return { records: [], total: 0, current: 1, size: 10 }
|
||||
}
|
||||
|
||||
// 状态机:请求失败,进入 error 状态
|
||||
loadingState.value = 'error'
|
||||
data.value = []
|
||||
if (!superseded) {
|
||||
// 状态机:请求失败,进入 error 状态
|
||||
loadingState.value = 'error'
|
||||
data.value = []
|
||||
}
|
||||
if (superseded) {
|
||||
// 旧请求的失败交给新请求兜底,不触发错误回调
|
||||
throw err instanceof Error ? err : new Error(String(err))
|
||||
}
|
||||
const tableError = handleError(err, '获取表格数据失败')
|
||||
throw tableError
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user