递归setTimeout()导致低cpu使用率

recursive setTimeout() causes low cpu usage

本文关键字:cpu 使用率 setTimeout 递归      更新时间:2023-09-26

我在JS中执行长计算。在计算过程中,我想显示一个进度条,在每一步之后更新。为了正确触发DOM刷新,我使用setTimeout对步骤进行排队。我自己构建了一个这样的函数:

var sequence = function (ar, callback, finalCallback) {
    if (ar && ar.length) {
        setTimeout(function () {
            callback && callback(ar.shift());
            sequence(ar, callback, finalCallback);
        }, 0);
    } else {
        finalCallback && finalCallback();
    }
};

这几乎像预期的那样工作。我在回调中正确地执行了计算和DOM操作。唯一的问题是,所有的东西都非常慢。计算过程中CPU占用率仅为20%。

我的代码有什么问题吗?我想,所有的单步只是排队,由于超时0得到执行没有'真正的'暂停,但当浏览器没有什么可做的了。

编辑:我试图在Chrome和Firefox中执行,两者的行为方式相同。此外,我试图移动setTimeout之外的实际回调调用。这没什么区别。

根据建议,我尝试setInterval而不是settimeout,像这样:

var sequence = function (ar, callback, finalCallback) {
    var interval = setInterval(function () {
        if (ar && ar.length) {
            callback && callback(ar.shift());
        } else {
            finalCallback && finalCallback();
            clearInterval(interval);
        }
    }, 0);
};

它的行为与setTimeout版本完全相同。

这是小提琴,它显示的东西:

https://jsfiddle.net/by6oovhz/8/

如果你删除setTimout,你会看到它实际上应该有多快(但DOM不再得到更新)。

我刚发现问题。setTimeout行为的原因是,这个方法总是有一个小的超时,即使你传递0作为参数。在这里,您可以阅读更多关于它的内容,并找到一个解决方法的链接。它使用窗口。postMessage创建一个函数,它的超时为0。

https://developer.mozilla.org/de/docs/Web/API/Window/setTimeout Minimum_delay_and_timeout_nesting

我认为你的函数已经触发了一大堆的超时对象到窗口。你可以试着这样修改你的函数,创建to,然后删除它。

myVar = setTimeout(function(){ mycallback }, 0); // id of timeout

和后面的代码中删除它

clearTimeout(myVar);

或者你可以尝试改变你的逻辑使用setInterval也许?

hth k