js 实现轮询
轮询的基本概念
轮询是一种客户端定期向服务器发送请求以获取最新数据的技术。适用于需要实时更新但无法使用WebSocket等长连接方案的场景。
简单轮询实现
使用setInterval创建定时器,定期发送请求:
function simplePolling(url, interval) {
setInterval(() => {
fetch(url)
.then(response => response.json())
.then(data => console.log('Updated data:', data))
.catch(err => console.error('Polling error:', err));
}, interval);
}
// 使用示例
simplePolling('/api/data', 3000); // 每3秒请求一次
带错误处理的增强版轮询
增加网络错误处理和请求超时控制:
function enhancedPolling(url, interval, timeout = 5000) {
const controller = new AbortController();
const signal = controller.signal;
const poll = () => {
setTimeout(() => controller.abort(), timeout);
fetch(url, { signal })
.then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(data => {
console.log('New data:', data);
setTimeout(poll, interval);
})
.catch(err => {
console.error('Polling failed:', err);
setTimeout(poll, interval * 2); // 错误时延长间隔
});
};
poll();
}
指数退避策略
网络不稳定时采用指数退避算法:
function exponentialBackoffPolling(url, maxInterval = 30000) {
let attempts = 0;
const baseInterval = 1000;
const poll = () => {
const delay = Math.min(baseInterval * Math.pow(2, attempts), maxInterval);
setTimeout(() => {
fetch(url)
.then(response => {
if (!response.ok) throw new Error(response.statusText);
attempts = 0;
return response.json();
})
.then(data => {
console.log('Data update:', data);
poll();
})
.catch(err => {
console.error(`Attempt ${attempts + 1} failed:`, err);
attempts++;
poll();
});
}, delay);
};
poll();
}
终止轮询的方法
需要停止轮询时可以使用以下方式:

let pollingInterval;
function startPolling() {
pollingInterval = setInterval(() => {
fetch('/api/data')
.then(/* ... */);
}, 2000);
}
function stopPolling() {
clearInterval(pollingInterval);
}
实际应用建议
- 重要数据轮询间隔建议不低于30秒
- 配合ETag或Last-Modified头减少不必要的数据传输
- 页面隐藏时(通过Visibility API)应暂停轮询
- 考虑使用Service Worker管理后台轮询
以上实现方案可根据具体需求组合使用,比如在简单轮询基础上增加错误处理和退避策略。






