如何延迟React Query请求调用?解决Jikan API并发限制问题
解决React Query中延迟请求适配Jikan API v4限流的问题
方案1:修改Fetcher函数,返回包含延迟逻辑的Promise
你的问题核心是animeUpcomingFetcher没有正确返回异步请求的结果——setTimeout是异步执行的,函数会直接返回初始的undefined,而非请求结果。要解决这个问题,需要把整个延迟+请求逻辑包装在Promise中,确保useQuery能等待异步操作完成:
const {data: animeUpcoming, isLoading: animeUpcomingLoading} = useQuery('animeByUpcoming', animeUpcomingFetcher) const animeUpcomingFetcher = () => { // 返回一个Promise,让useQuery等待异步结果 return new Promise(async (resolve, reject) => { setTimeout(async () => { try { const res = await axios('https://api.jikan.moe/v4/top/anime?filter=upcoming&limit=6') resolve(res.data) // 通常只需返回响应的data部分,可根据需求调整 } catch (error) { reject(error) // 抛出错误,让React Query捕获并处理 } }, 1200) }) }
方案2:用React Query的enabled选项控制请求时机(更推荐)
这种方式将延迟逻辑与数据获取分离,更符合React Query的设计理念,还能统一控制多个延迟请求的触发时间:
import { useState, useEffect } from 'react' import { useQuery } from 'react-query' function AnimePage() { // 状态控制延迟请求是否启用 const [enableDelayedQueries, setEnableDelayedQueries] = useState(false) // 组件挂载后,延迟1.2秒启用后续请求 useEffect(() => { const timer = setTimeout(() => { setEnableDelayedQueries(true) }, 1200) // 组件卸载时清除定时器,避免内存泄漏 return () => clearTimeout(timer) }, []) // 正常执行的两个请求 const { data: popularAnime } = useQuery('animeByPopular', () => axios('https://api.jikan.moe/v4/top/anime?filter=bypopularity&limit=6').then(res => res.data) ) const { data: airingAnime } = useQuery('animeByAiring', () => axios('https://api.jikan.moe/v4/top/anime?filter=airing&limit=6').then(res => res.data) ) // 延迟执行的请求,通过enabled控制触发时机 const { data: animeUpcoming, isLoading: animeUpcomingLoading } = useQuery( 'animeByUpcoming', () => axios('https://api.jikan.moe/v4/top/anime?filter=upcoming&limit=6').then(res => res.data), { enabled: enableDelayedQueries } // 仅当enableDelayedQueries为true时发起请求 ) const { data: topRatedAnime, isLoading: topRatedLoading } = useQuery( 'animeByTopRated', () => axios('https://api.jikan.moe/v4/top/anime?filter=all&limit=6').then(res => res.data), { enabled: enableDelayedQueries } ) // 渲染逻辑... }
额外注意事项
- 可根据Jikan API v4的限流规则调整延迟时间,比如如果1.2秒仍触发限流,可延长至2秒或更久
- 建议在请求中添加错误处理,避免单个请求失败导致页面异常
- 如果需要更复杂的请求排队逻辑,可考虑结合axios拦截器实现重试或排队机制
内容的提问来源于stack exchange,提问作者Zio-4
相关产品推荐
相关产品推荐

