js实现轮询
轮询的基本概念
轮询是一种客户端定期向服务器发送请求以获取最新数据的技术。适用于需要实时更新但无法使用WebSocket或Server-Sent Events的场景。
使用setInterval实现基础轮询
通过setInterval定时发起请求,以下是一个简单示例:

function pollServer() {
fetch('/api/data')
.then(response => response.json())
.then(data => {
console.log('Received data:', data);
})
.catch(error => {
console.error('Polling error:', error);
});
}
const intervalId = setInterval(pollServer, 5000); // 每5秒轮询一次
// 停止轮询
// clearInterval(intervalId);
带退避策略的轮询
当服务器负载较高时,可采用指数退避策略:

let retryDelay = 1000;
const maxDelay = 60000;
function pollWithBackoff() {
fetch('/api/data')
.then(response => {
retryDelay = 1000; // 成功时重置延迟
return response.json();
})
.then(data => {
console.log('Data received:', data);
setTimeout(pollWithBackoff, 5000);
})
.catch(error => {
console.error('Error:', error);
retryDelay = Math.min(retryDelay * 2, maxDelay);
setTimeout(pollWithBackoff, retryDelay);
});
}
pollWithBackoff();
条件轮询实现
仅在特定条件满足时继续轮询:
let shouldPoll = true;
function conditionalPoll() {
if (!shouldPoll) return;
fetch('/api/status')
.then(response => response.json())
.then(data => {
if (data.needsUpdate) {
fetch('/api/data').then(/* ... */);
}
setTimeout(conditionalPoll, 3000);
});
}
conditionalPoll();
// 停止条件
// shouldPoll = false;
基于Promise的轮询
封装为可复用的Promise链式调用:
function createPoller(url, interval, callback) {
let stopped = false;
const executePoll = () => {
if (stopped) return;
fetch(url)
.then(response => response.json())
.then(data => {
callback(null, data);
setTimeout(executePoll, interval);
})
.catch(err => {
callback(err);
setTimeout(executePoll, interval);
});
};
executePoll();
return {
stop: () => { stopped = true; }
};
}
// 使用示例
const poller = createPoller('/api/data', 2000, (err, data) => {
if (err) return console.error(err);
console.log('Polling data:', data);
});
// 停止
// poller.stop();
轮询的优化建议
- 添加请求取消逻辑,避免组件卸载时继续请求
- 考虑使用
AbortController中断正在进行的请求 - 对于重要数据,可结合本地缓存进行比较
- 在页面不可见时(通过Page Visibility API)暂停轮询
以上实现方案可根据具体需求进行组合或调整,注意在SPA应用中组件卸载时清除轮询定时器。






