首页 > 解决方案 > 避免 setInterval/setTimeout?

问题描述

我有以下问题:在我的函数中setInterval()setTimeout()我不断地重复一个动作i。由于 setInterval 或 setTimeout 的延迟(我认为是后者),一段时间后脚本停止正常工作,几个任务会同时发生。

该脚本在 WhatsApp Web 上使用,点击前 16 个联系人,检查每个联系人的在线状态。如果联系人在线,它会打印日志。问题如下:在 aomw 时间(3 小时左右)之后,间隔在旧功能完成之前重复自身。所以我得到 14,1,15,2,16,3,1,4... 而不是 1,2,3,5...

setInterval(function () {
    function writeNext(i) {
        if (i == 17)
            return;

        setTimeout(function () {
            writeNext(i + 1);
            selectContact(`${i}`)

            if (document.getElementsByClassName("O90ur")[0] !== undefined) {
                var online = document.getElementsByClassName("O90ur")[0].innerHTML
                    if (online == "online") {
                        console.log(`${i-1}`)
                    };
            }

        }, 1250);
    }

    writeNext(1);
}, 20000);

标签: javascriptsettimeoutsetinterval

解决方案


您的计时器setTimout非常接近20000 / 17。如果递归的时间不准确,您将开始看到重叠,setInterval在所有 17 个旧超时完成之前,下一个开始调用新超时。javascript中的计时器也不能保证精确到高分辨率。

如果您只想让某些东西在循环中连续运行,请考虑仅使用setInterval和计算i % 17. 例如:

let i = 1
setInterval(function () {
     // do stuff with `i`
     console.log(i)
     i = i % 17 + 1
}, 400);

It will be easier to debug and understand and won't have any chance of overlap.


推荐阅读