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

3
以下函数在我的电脑上占用了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个回答

1

与其反复调用稍有不同的setTimeout,您可以设置全局变量来跟踪当前迭代,并使用一次setInterval()调用。setInterval类似于setTimeout,但它将无限期地运行 - 您不必再次调用它。这可能会有所帮助。


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>

1

这个应该不会占用100%的CPU。(但实际表现取决于文档大小)然而,一个显而易见的改进是摆脱setTimeout中隐式的eval

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)。


0

不,即使按照原样编写,它也不会占用我100%的CPU。

你应该首先更改你的writeToLog函数。追加HTML块比读取现有的HTML、添加文本+BR和将整个内容重新写入要快得多。

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

}

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接