译零 TransZero · TanStack Query 中文文档
主站

轮询(Polling)

更新于 2026-11-02 Solid 查看英文原文 ↗

refetchInterval 使查询按定时器重新拉取。将其设为以毫秒为单位的数值,查询将在至少存在一个活跃观察者时,每隔 N 毫秒执行一次:

TypeScript
1useQuery(() => ({2  queryKey: ['prices'],3  queryFn: fetchPrices,4  refetchInterval: 5 * 1000, // every 5 seconds5}))

轮询与 staleTime 相互独立。一个查询即使处于新鲜(fresh)状态,仍会按计划轮询;有关 staleTime 如何与其他重新拉取行为交互,请参阅 重要默认值。refetchInterval 始终基于其自身的时钟触发,不受 freshness 状态影响。

根据查询状态动态调整轮询间隔

可传入一个函数而非固定数值,以根据当前查询状态动态计算轮询间隔。该函数接收 Query 对象作为参数,并应返回以毫秒为单位的数值,或返回 false 以停止轮询:

TypeScript
1useQuery(() => ({2  queryKey: ['job', jobId],3  queryFn: () => fetchJobStatus(jobId),4  refetchInterval: (query) => {5    // Stop polling once the job finishes6    if (query.state.data?.status === 'complete') return false7    return 2 * 10008  },9}))

返回 false 将清除间隔定时器。若查询结果发生变化,导致该函数再次返回正数,则轮询将自动恢复。

后台轮询

默认情况下,当浏览器标签页失去焦点时,轮询会暂停。对于仪表盘类应用,或任何需要在用户切换至其他标签页时仍保持数据实时性的界面,可禁用该行为:

TypeScript
1useQuery(() => ({2  queryKey: ['portfolio'],3  queryFn: fetchPortfolio,4  refetchInterval: 30 * 1000,5  refetchIntervalInBackground: true,6}))

暂停轮询

向 refetchInterval 传入一个函数,并在其中闭包捕获组件状态,即可控制轮询的启停时机:

TypeScript
1useQuery(() => ({2  queryKey: ['prices', tokenAddress],3  queryFn: () => fetchPrice(tokenAddress),4  refetchInterval: () => {5    if (!tokenAddress || isPaused) return false6    return 15 * 10007  },8}))

支持离线状态的轮询

TanStack Query 通过监听浏览器的 online 和 offline 事件来检测网络连接状态。在这些事件无法可靠触发的环境中(例如 Electron 或某些嵌入式 WebView),可设置 networkMode: 'always' 以跳过连通性检查:

TypeScript
1useQuery(() => ({2  queryKey: ['chainStatus'],3  queryFn: fetchChainStatus,4  refetchInterval: 10 * 1000,5  networkMode: 'always',6}))

有关网络模式的更多说明,请参阅 Network Mode。

关于去重的说明

每个 QueryObserver(即每个使用 useQuery 并配置了 refetchInterval 的组件)都运行各自的定时器。两个订阅相同查询键且均设置了 refetchInterval: 5 * 1000 的组件,各自都会每 5 秒触发一次定时器。真正被去重的是并发进行中的拉取请求:若两个定时器同时触发,则仅发出一次网络请求。定时器作用于观察者(observer)层级,而去重则发生在查询(query)层级。

本页为 TanStack Query 文档(Solid 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de