如何优化调用setTimeout()的递归函数

时间:2011-12-29 19:02:45

标签: javascript jquery html

以下功能在我的计算机上使用100%的CPU内核。有没有办法可以将其重写为非递归?这会解决它还是因为我的CPU很糟糕?其他人是否在他们的计算机上看到相同的性能问题?

代码:

<html>
<head>
    <script type="text/javascript" src="jquery-1.7.1.js"></script>
    <script type="text/javascript">
        function timeMsg(n,max,delay)
        {
            writeToLog(n + "th: &#" + n,n);
            var temp = n + 1;
            if(n < max){
                var t=setTimeout("timeMsg(" + temp + "," + max + "," + delay + ")",delay);
            }

        }
        function writeToLog(text,n){
            $("#log").html($("#log").html() + text + "<br/>");
            //autoscrolling: doesn't work...'

        }
    </script>
</head>

<body>
    <form>
        <input type="button" value="Display alert box in 3 seconds" onClick="timeMsg(0,100000,100)" />
    </form>

    <div id="log"></div>

</body>

4 个答案:

答案 0 :(得分:1)

那不应该使用100%的CPU。 (但实际的性能取决于文档的大小。)然而,一个明显的改进是摆脱eval中隐含的setTimeout

function timeMsg(n, max, delay) {
    writeToLog(n + "th: &#" + n, n);
    var temp = n + 1;
    if(n < max) {
        var t = setTimeout(function() {
            timeMsg(temp, max, delay);
        }, delay);
    }
}

您还应该使用append代替您目前使用的双html(反)模式:

function writeToLog(text,n){
    $("#log").append(text + "<br/>");
}

无需搜索#log两次(两次都读html)。

答案 1 :(得分:1)

您可以设置全局变量来跟踪当前迭代,而不是重复调用具有稍微不同值的setTimeout,而是使用一次调用setInterval()。 setInterval就像setTimeout一样,除了它会无限期地运行 - 你不必一遍又一遍地调用它。这可能会有所帮助。

答案 2 :(得分:1)

使用setInterval()开始,clearInterval()达到最大值

演示:http://jsfiddle.net/ThinkingStiff/PwASf/

脚本:

var timer;

function startMsg( n, max, delay ) {

    timer = window.setInterval( function() {
        timeMsg( n++, max );
    }, delay );;

};

function timeMsg( temp, max ) {

    writeToLog(temp + "th: &#" + temp, temp);

    if( temp == max ){
        window.clearInterval( timer );
    }

}

function writeToLog(text,n){
    $(' #log' ).append( text + '<br/>' );
}

startMsg( 1, 10, 1000 );

HTML:

<div id="log"></div>

答案 3 :(得分:0)

不,即使写完,它也不会为我使用100%的CPU。

您应该做的第一件事是更改writeToLog函数。附加HTML块必须比1)读取现有的HTML更快,2)添加文本+ BR,3)将整个内容写回来。

function writeToLog(text,n){
       $("#log").append(text + "<br/>");
        //autoscrolling: doesn't work...'

}

除此之外,如果你不想阻止其他JS运行,那么你需要使用setTimeout / setInterval方法来实现这个循环。否则,常规for循环会更快。