Vue Query 查询失败自动重试(Query Retries)完整指南:从默认策略到源码级实现
发布时间:2026/9/11 4:28:58 锦皓数字建站
完整指南:从默认策略到源码级实现`)
Vue Query 查询失败自动重试Query Retries完整指南从默认策略到源码级实现【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query当网络请求失败时应用直接展示错误还是静默重试直接决定用户体验。TanStack Vue Query 内置了一套开箱即用的自动重试机制查询函数queryFn抛出异常后只要没有达到最大连续重试次数Vue Query 就会自动重新发起请求。本文围绕 query-retries.md 指南系统讲解 Vue Query 重试的默认行为、retry与retryDelay的四种取值方式、全局与单查询两级配置并结合tanstack/query-core的 retryer.ts 源码剖析重试循环、指数退避与暂停机制的底层实现。读完你将能在真实项目中精准控制失败请求的重试次数、节奏与后台行为。重试机制的工作原理与默认行为当useQuery的查询函数抛错时TanStack Vue Query 会自动重试该查询——前提是它尚未达到最大连续重试次数默认3次或者你提供的是一个用于判断是否允许重试的函数。默认值在tanstack/query-core的 retryer.ts 中有明确实现const retry config.retry ?? (isServerEnvironment() ? 0 : 3)也就是说浏览器/客户端环境默认重试3次服务端环境默认重试0次——为了让服务端渲染SSR尽可能快Vue Query 在服务端关闭了自动重试避免阻塞首屏 HTML 输出。这一默认策略同时适用于 Vue 生态中的 Nuxt / SSR 场景可参考 docs/framework/vue/overview.md 中的 SSR 相关说明。重试可以同时在全局级别和单个查询级别进行配置单查询配置的优先级更高。retry 的四种取值从完全关闭到无限重试retry选项接受布尔值、数字或自定义函数四种典型用法如下retry false完全禁用重试请求失败后立即抛出最终错误retry 6失败请求最多重试6次之后展示查询函数最终抛出的错误retry true无限重试失败请求直到成功为止需谨慎使用可能造成请求风暴retry (failureCount, error) ...根据失败原因自定义重试逻辑例如只对特定 HTTP 状态码或网络错误重试。注意首次重试尝试时failureCount从0开始。从类型定义看retryer.tsretry的类型是export type RetryValueTError boolean | number | ShouldRetryFunctionTError type ShouldRetryFunctionTError DefaultError ( failureCount: number, error: TError, ) boolean而是否重试的判定逻辑retryer.ts为const shouldRetry retry true || (typeof retry number failureCount retry) || (typeof retry function retry(failureCount, error))由此可以精确推算出行为边界当retry为数字n时只要failureCount n就继续重试即失败后总计会执行n 1次请求1 次原始请求 n 次重试函数形式则完全交由你的业务逻辑决定。在单个查询上配置重试次数对某个特定查询单独指定重试次数是文档中给出的第一种典型用法import { useQuery } from tanstack/vue-query // 让某个特定查询重试指定次数 const result useQuery({ queryKey: [todos, 1], queryFn: fetchTodoListPage, retry: 10, // 在显示错误之前最多重试失败的请求 10 次 })上面的配置意味着fetchTodoListPage失败后会最多被重试 10 次总共最多 11 次请求尝试。这种按查询定制的方式非常适合对关键数据如核心业务列表、支付状态轮询提高容错而对非关键数据如表单校验、一次性操作关闭重试。failureReason 与 error重试期间的两个错误属性重试机制中有一个容易踩坑的细节useQuery返回结果中的error属性在最后一轮重试结束前并不会承载最新失败的错误内容。根据官方指南的说明error属性的内容在最后一次重试尝试之前都会进入failureReason响应属性。以上面retry: 10的例子为例前 9 次重试共 10 次尝试期间的错误内容都在failureReason中如果 10 次尝试全部失败最后一次的错误才会进入error。这一行为在源码中有对应实现createRetryer每次失败后会调用config.onFail?.(failureCount, error)retryer.ts并在 query.ts 中派发failed动作onFail: (failureCount, error) { this.#dispatch({ type: failed, failureCount, error }) }随后观察者状态中的fetchFailureCount与fetchFailureReason会被同步更新queryObserver.tsfailureCount: newState.fetchFailureCount, failureReason: newState.fetchFailureReason,因此若想在重试期间实时感知当前失败原因例如在 UI 上展示渐进式降级提示应读取failureReason若想确定彻底失败则应判断error。全局配置重试延迟VueQueryPlugin 与指数退避默认情况下Vue Query 的重试不会在请求失败后立即发生。作为行业标准做法每次重试尝试之间会逐渐施加一个退避延迟back-off delay。默认的retryDelay以1000ms 起步、每次尝试翻倍且不超过 30 秒其公式在 retryer.ts 中实现function defaultRetryDelay(failureCount: number) { return Math.min(1000 * 2 ** failureCount, 30000) }即延迟序列为 1000ms → 2000ms → 4000ms → 8000ms → 16000ms → 30000ms此后封顶……要为所有查询全局配置retryDelayVue 版本需要借助VueQueryPlugin的queryClientConfig选项这是 Vue 指南文档的核心示例import { VueQueryPlugin } from tanstack/vue-query const vueQueryPluginOptions { queryClientConfig: { defaultOptions: { queries: { retryDelay: (attemptIndex) Math.min(1000 * 2 ** attemptIndex, 30000), }, }, }, } app.use(VueQueryPlugin, vueQueryPluginOptions)从 vueQueryPlugin.ts 的源码可以看到queryClientConfig会被直接用于构造QueryClientif (queryClient in options options.queryClient) { client options.queryClient } else { const clientConfig queryClientConfig in options ? options.queryClientConfig : undefined client new QueryClient(clientConfig) }这意味着queryClientConfig支持 QueryClient 构造参数中的全部字段其中defaultOptions.queries.retryDelay即为所有查询的默认重试延迟。插件安装后会在非服务端环境调用client.mount()并完成依赖注入app.provide(clientKey, client)可参考 installation.md 与 quick-start.md。覆盖单个查询的重试延迟官方文档明确指出虽然不推荐但你可以在全局Plugin和单个查询选项中覆盖retryDelay函数或整数。如果传入的是整数而非函数那么无论重试多少次延迟始终是同一个固定时长const result useQuery({ queryKey: [todos], queryFn: fetchTodoList, retryDelay: 1000, // 无论重试多少次总是等待 1000ms 再重试 })retryDelay的类型定义retryer.ts与计算方式retryer.ts如下export type RetryDelayValueTError number | RetryDelayFunctionTError type RetryDelayFunctionTError DefaultError ( failureCount: number, error: TError, ) number // 实际计算 const delay typeof retryDelay function ? retryDelay(failureCount, error) : retryDelay函数形式可以基于failureCount和当前error动态决定延迟例如对限流类错误HTTP 429/503返回更长的等待时间。注意当retry为false或数字 0 时retryDelay不会生效因为根本不会进入重试分支。后台重试行为标签页失焦时自动暂停当查询配置了refetchInterval且refetchIntervalInBackground: true时重试会在浏览器标签页处于非激活状态时暂停。这是因为重试遵循与常规 refetch 相同的焦点focus行为。这一机制在 retryer.ts 的canContinue中实现const canContinue () focusManager.isFocused() (config.networkMode always || onlineManager.isOnline()) config.canRun()每次重试前会先sleep(delay)随后判断canContinue()如果文档不可见或设备离线就进入pause()等待恢复retryer.tssleep(delay) // 当文档不可见或设备离线时暂停 .then(() { return canContinue() ? undefined : pause() }) .then(() { if (isRetryCancelled) { reject(error) } else { run() } })如果你需要在后台持续重试官方建议关闭内置重试改为自定义 refetch 策略const result useQuery({ queryKey: [todos], queryFn: fetchTodos, refetchInterval: (query) { // 处于错误状态时更频繁地重新请求 return query.state.status error ? 5000 : 30000 }, refetchIntervalInBackground: true, retry: false, // 关闭内置重试 })这种方案把重试时机的控制权完全交给你错误状态下每 5 秒自动重新拉取一次正常状态下每 30 秒一次同时保持后台 refetch 持续激活。源码视角重试器的完整执行循环将以上行为串联起来createRetryerpackages/query-core/src/retryer.ts内部的执行循环可以概括为run()调用查询函数首次可复用initialPromise成功则resolve失败时先解析retry默认值服务端0客户端3与retryDelay默认指数退避依据shouldRetry判定true/ 数字比较 / 自定义函数决定是否继续若继续failureCount回调onFail驱动failureReason/failureCount状态更新随后sleep(delay)睡眠结束后检查canContinue()焦点 在线状态不满足则pause()挂起等待窗口聚焦或网络恢复恢复后若未被cancelRetry取消则再次run()形成闭环一旦达到最大次数或函数返回false立即reject(error)。整个重试器与focusManager、onlineManager深度联动见 focusManager.md 与 onlineManager.md这也是为什么离线/失焦场景下重试会被智能挂起而非盲目轰炸服务端。小结Vue Query 默认在客户端重试3次、服务端重试0次retry支持false/ 数字 /true/ 自定义函数四种形态全局配置通过VueQueryPlugin的queryClientConfig.defaultOptions.queries注入单查询可通过useQuery选项覆盖默认重试延迟为Math.min(1000 * 2 ** failureCount, 30000)的指数退避也可传整数固定延迟重试期间的最新错误位于failureReason最终错误才进入error后台重试遵循焦点/在线策略标签页失焦时自动暂停需要持续后台重试时应关闭内置重试并自定义 refetch 策略。掌握以上配置与原理你就能让 Vue Query 的网络容错行为既稳健又可控。【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。