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