js通过setTimeout实现可停止轮询

257 阅读1分钟

在项目中我们常常会遇到需要轮询接口获取数据的情况,但是这种接口轮询获取数据的情形又不适合使用websoket等长连接,这个时候我们就会考虑到使用setInterval函数去实现。当网络较慢,接口响应过慢的时候会出现上一个轮询的接口还未获取到响应数据时下一个接口已经发送并同时返回响应结果。这个时候setInterval就不太适合了。

下面这个函数是自己实现的仿setInterval函数的功能,它可以实现当上一个接口返回数据后再开始下一次的轮询,并且在不需要接口轮询时调用stop()函数停止此轮询。当接口返回报错时自动停止该轮询任务。

function myInterval(callback, interbal = 3000) {
    let timer = null;
    let isStop = false;
    const stop = () => {
        isStop = true
        clearTimeout(timer)
    }
    const start = async () => {
        isStop = false
        await loop()
    }
 
    const loop = async () => {
        try {
            await callback(stop)
            if (isStop) return
            return timer = setTimeout(loop, interbal)
        } catch (e) {
            stop()
            throw new Error('轮询出错')
        }
        
    }
}
 
function main(stop) {
    // 可调用stop停止轮询
}
 
const intervalManager = myInterval(main)
 
intervalManager.start()