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

时间:2015-05-16 10:05:22

标签: javascript timeout progress

我在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代替setTimout,如下所示:

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不会再被更新)。

2 个答案:

答案 0 :(得分:2)

我刚发现了这个问题。 setTimeout行为的原因是,即使您将0作为参数传递,此方法也始终具有较小的超时。在这里,您可以阅读更多相关信息,并找到工作区的链接。它使用window.postMessage创建一个实际上超时为零的函数。

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

答案 1 :(得分:0)

我认为你的func已经向窗口发出了一堆超时obj .. 您可以尝试将您的功能更改为此类,以创建TO然后将其删除..

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

后者在代码中将其删除

clearTimeout(myVar);

或者您可以尝试更改逻辑以使用setInterval吗?

hth,k