轮询更适合用 setTimeout 循环调用而非 setInterval,因其能根据响应结果决定是否继续、何时继续,避免请求堆积与状态错乱,支持动态调间隔和安全终止。

轮询更适合用 setTimeout 循环调用,而不是 setInterval。
轮询的本质是“有控制的重复请求”
轮询不是无条件地每隔固定时间就发一次请求,而是需要根据上一次响应结果决定是否继续、何时继续。比如支付状态查询:收到“支付中”才需再查,收到“成功”或“失败”就该立即停止。
- setInterval 会盲目执行,不管前一次请求是否完成、返回什么结果
- 它可能在上一个请求还没返回时就发起下一个,造成请求堆积或状态错乱
- 如果某次请求耗时超过设定间隔(比如设了 2s,但接口花了 3.5s),后续请求会“挤在一起”,甚至并发激增
setTimeout 循环调用更可控
每次都在上一次请求完成后再决定下一次调用时机,天然适配异步流程。
- 可以在 success 或 error 回调里调用下一个 setTimeout,确保串行、不重叠
- 能根据响应动态调整下次延迟时间(如首次 1s,后续逐步延长至 5s)
- 容易插入终止逻辑:比如收到终态响应、超时、用户取消,直接不调用下一次即可
实际写法对比
不推荐的 setInterval 写法:
let timer = setInterval(() => { fetchOrderStatus().then(handleResponse); }, 2000);
→ 无法感知请求是否完成,不能及时停,也不能动态调间隔
推荐的 setTimeout 循环写法:
function poll() {
fetchOrderStatus()
.then(res => {
if (res.status === 'pending') setTimeout(poll, 2000);
else stopPolling();
});
}
poll();
→ 每次只在确认需要时才安排下一次,干净、安全、可中断
额外注意点
无论选哪种方式,都必须做到:
- 保存定时器 ID(timeoutID 或 intervalID),并在退出页面、组件卸载或轮询结束时主动清除
- 避免因未清除导致内存泄漏或后台持续请求
- 对轮询设置最大次数或总超时时间,防止无限循环

















