簡體   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