js中实现轮询
轮询的基本概念
轮询是一种通过定期向服务器发送请求来检查数据更新的技术。适用于需要实时性但无法使用WebSocket或Server-Sent Events(SSE)的场景。
使用 setInterval 实现基础轮询
通过 setInterval 定时触发请求,适合简单场景:
function pollServer() {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log('更新数据:', data))
.catch(error => console.error('请求失败:', error));
}
const pollInterval = setInterval(pollServer, 5000); // 每5秒轮询一次
// 停止轮询
// clearInterval(pollInterval);
使用递归 setTimeout 实现可控轮询
递归调用 setTimeout 可灵活调整间隔时间或根据条件停止:
function pollServer() {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log('数据更新:', data);
if (data.needsUpdate) {
setTimeout(pollServer, 1000); // 数据需更新时缩短间隔
} else {
setTimeout(pollServer, 5000); // 否则恢复默认间隔
}
})
.catch(error => {
console.error('请求失败:', error);
setTimeout(pollServer, 10000); // 失败时延长间隔
});
}
pollServer(); // 启动轮询
结合指数退避算法优化轮询
在网络不稳定时,通过指数退避减少请求压力:
let retryCount = 0;
const maxDelay = 60000; // 最大退避时间(毫秒)
function pollServer() {
fetch('https://api.example.com/data')
.then(response => {
retryCount = 0; // 成功时重置重试计数
return response.json();
})
.then(data => console.log('数据:', data))
.catch(error => {
retryCount++;
const delay = Math.min(1000 * Math.pow(2, retryCount), maxDelay);
console.error(`请求失败,${delay}ms后重试:`, error);
setTimeout(pollServer, delay);
});
}
pollServer();
终止轮询的条件控制
通过标志变量或AbortController主动终止请求:

let isPollingActive = true;
const controller = new AbortController();
function pollServer() {
if (!isPollingActive) return;
fetch('https://api.example.com/data', { signal: controller.signal })
.then(response => response.json())
.then(data => {
console.log('数据:', data);
setTimeout(pollServer, 5000);
})
.catch(error => {
if (error.name !== 'AbortError') {
console.error('请求失败:', error);
setTimeout(pollServer, 5000);
}
});
}
pollServer();
// 终止轮询
function stopPolling() {
isPollingActive = false;
controller.abort();
}
实际应用建议
- 频率选择:根据业务需求调整间隔,避免过高频率导致服务器压力。
- 错误处理:添加网络异常、超时等情况的处理逻辑。
- 兼容性:旧浏览器需使用
XMLHttpRequest替代fetch。






