js实现poll函数
实现 Poll 函数的方法
在 JavaScript 中,poll 函数通常用于定期检查某个条件是否满足,直到条件为真或超时。以下是几种实现方式:
基础实现
使用 setInterval 定期检查条件,满足后清除定时器:
function poll(fn, condition, interval = 100, timeout = 5000) {
const endTime = Date.now() + timeout;
const checkCondition = () => {
const result = fn();
if (condition(result)) {
return Promise.resolve(result);
}
if (Date.now() > endTime) {
return Promise.reject(new Error('Timeout exceeded'));
}
return new Promise(resolve => {
setTimeout(() => resolve(checkCondition()), interval);
});
};
return checkCondition();
}
使用 async/await
更现代的异步实现方式:
async function poll(fn, condition, interval = 100, timeout = 5000) {
const endTime = Date.now() + timeout;
while (true) {
const result = await fn();
if (condition(result)) return result;
if (Date.now() > endTime) throw new Error('Timeout exceeded');
await new Promise(resolve => setTimeout(resolve, interval));
}
}
带取消功能的实现
添加取消机制,允许提前终止轮询:

function cancellablePoll(fn, condition, interval = 100, timeout = 5000) {
let timer;
let rejected = false;
const promise = new Promise((resolve, reject) => {
const endTime = Date.now() + timeout;
const checkCondition = () => {
if (rejected) return;
const result = fn();
if (condition(result)) {
resolve(result);
} else if (Date.now() > endTime) {
reject(new Error('Timeout exceeded'));
} else {
timer = setTimeout(checkCondition, interval);
}
};
checkCondition();
});
promise.cancel = () => {
clearTimeout(timer);
rejected = true;
};
return promise;
}
使用示例
// 检查某个元素是否出现在DOM中
poll(
() => document.querySelector('.target-element'),
element => element !== null,
200,
10000
).then(element => {
console.log('Element found:', element);
}).catch(err => {
console.error('Polling failed:', err);
});
// 可取消的示例
const polling = cancellablePoll(
() => Math.random(),
val => val > 0.9,
100,
5000
);
// 可以调用 polling.cancel() 提前终止
setTimeout(() => polling.cancel(), 2000);
polling.then(val => {
console.log('Got value:', val);
}).catch(err => {
console.error('Polling failed:', err);
});
注意事项
轮询间隔不宜过短,避免性能问题 超时时间应根据实际需求合理设置 对于DOM操作,考虑使用 MutationObserver 替代轮询更高效 取消功能对于长时间运行的任务很有必要






