js中实现轮询
轮询的基本概念
轮询是一种通过定时请求服务器来检查数据更新的技术。适用于需要实时性但无法使用WebSocket或Server-Sent Events的场景。
使用 setInterval 实现基础轮询
通过 setInterval 定时发起请求,代码简洁但可能因网络延迟导致请求堆积:

function pollServer() {
fetch('/api/check-update')
.then(response => response.json())
.then(data => {
if (data.updated) {
// 处理更新逻辑
}
});
}
const pollInterval = setInterval(pollServer, 5000); // 每5秒轮询一次
// 停止轮询
// clearInterval(pollInterval);
递归 setTimeout 实现可控轮询
递归调用 setTimeout 可在每次请求完成后调整下次轮询时间,避免请求重叠:
function pollWithTimeout() {
fetch('/api/check-update')
.then(response => response.json())
.then(data => {
if (data.updated) {
// 处理更新逻辑
}
setTimeout(pollWithTimeout, 5000); // 下一次轮询
})
.catch(error => {
console.error('轮询失败:', error);
setTimeout(pollWithTimeout, 10000); // 失败时延长间隔
});
}
pollWithTimeout(); // 启动轮询
指数退避策略优化
在网络不稳定时,采用指数退避逐步增加轮询间隔:

let retryDelay = 1000;
const maxDelay = 60000;
function pollWithBackoff() {
fetch('/api/check-update')
.then(response => {
retryDelay = 1000; // 成功时重置延迟
return response.json();
})
.then(data => {
if (data.updated) {
// 处理更新逻辑
}
setTimeout(pollWithBackoff, 5000);
})
.catch(error => {
retryDelay = Math.min(retryDelay * 2, maxDelay);
console.error(`请求失败,${retryDelay / 1000}秒后重试`);
setTimeout(pollWithBackoff, retryDelay);
});
}
pollWithBackoff();
基于条件的动态轮询
根据业务需求动态调整轮询频率(如无更新时延长间隔):
let currentInterval = 5000;
function dynamicPoll() {
fetch('/api/check-update')
.then(response => response.json())
.then(data => {
if (data.updated) {
currentInterval = 2000; // 高频轮询
// 处理更新逻辑
} else {
currentInterval = 10000; // 低频轮询
}
setTimeout(dynamicPoll, currentInterval);
});
}
dynamicPoll();
终止轮询的注意事项
确保在组件卸载或页面跳转时清理轮询,避免内存泄漏:
let pollTimer;
function startPolling() {
function poll() {
fetch('/api/data').then(/* ... */);
pollTimer = setTimeout(poll, 3000);
}
poll();
}
// 清理函数示例
function stopPolling() {
if (pollTimer) {
clearTimeout(pollTimer);
}
}
// 页面卸载时调用 stopPolling()
性能优化建议
- 请求去重:避免并发重复请求。
- 轻量响应:要求API返回最小必要数据。
- 条件请求:使用
Last-Modified或ETag头部减少数据传输。 - 退避上限:设置最大重试间隔(如60秒)。






