[英]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.