繁体   English   中英

递归函数和setTimeout()问题

[英]recursive function and setTimeout() problem

我有一个脚本可以在画布上绘制一堆线条,但是它非常紧张,因此渲染时会冻结浏览器几秒钟。 我添加了setTimeout(),以使浏览器不会冻结,并且有效地弄乱了我的脚本。 很难解释如何执行,因此我在网上有两个示例:

没有setTimeout(): http : //www.modwebsolutions.com/test1

使用setTimeout(): http : //www.modwebsolutions.com/test2

注意,我只更改了整个脚本中的一行,即第69行:
没有setTimeout(): vLoop();
与setTimeout(): setTimeout(vLoop,1);

正如其他人所暗示的,这里的问题是您一次绘制一条象限。 一旦调用SetTimeout方法并返回第一个vLoop ,代码就会继续运行到下一个drawVertical ,后者将更改所有全局变量,依此类推。

您需要做的是同步调用vLoop的方式以及更改全局变量的方式。

这基本上是解决方案:

更换...

drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0); 
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0);

...与...

var q = new Array();
q[0] = [c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y];
q[1] = [c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y];
q[2] = [c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0];
q[3] = [c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0];

drawQuadrant(q, 0);

用...替换drawVertical函数

function drawQuadrant(q, i)
{
    var r = q[i];

    c__ = r[0];
    step__ = r[1];
    stepInt__ = r[2];
    bigStep__ = r[3];
    xStart__ = r[4];
    xEnd__ = r[5];
    yStart__ = r[6];
    yEnd__ = r[7]; 


    vLoop(q,i);
}

vLoop函数原型更改为如下所示...

function vLoop(q,i)

最后用...替换您的递归vLoop调用(从vLoop内部)

if ((xStart__ > 0) && (xStart__ < window.innerWidth))
{
    setTimeout( function(){vLoop(q,i)}, 1 );
}
else if (++i < 4)
{
    setTimeout( function(){drawQuadrant(q,i)}, 1 );
}

最后一块是确保象限彼此不交叉的地方。

drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0); 
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0);

您一次调用vLoop 4个递归函数。 这里的问题是setTimeout是非阻塞的,因为递归正在阻塞。 因此,基本上,您现在具有了所有四个drawVertical函数,它们并行运行,而不是依次运行。

另一个问题是所有4个对象都引用并弄乱了全局状态,并且整个程序都中断了。

发生的事情是setTimeout() 所有执行延迟到以后。 不幸的是,到那时为止,您的全局变量已从初始循环移至其结束位置,因为它在绘制第一行之前就已完成。

如果您将超时时间进一步调高(因此直到绘制时间才影响您使用的共享变量),那么您可以实现所追求的目标,例如:

setTimeout(function() {
    drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y);
    drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y);
    drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0);
    drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0);
});

那样就可以了(但是很危险,命令不是绝对必须的!)

您可以在此处看到一个有效的示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM