рекурсивная функция и проблема setTimeout () - PullRequest
0 голосов
/ 24 апреля 2011

У меня есть скрипт, который рисует несколько линий на холсте, но он довольно интенсивный, поэтому при рендеринге браузер останавливается на несколько секунд Я добавил setTimeout (), чтобы браузер не зависал, и он фактически испортил мой скрипт. Трудно объяснить, как, поэтому у меня есть два примера в Интернете:

Без setTimeout (): http://www.modwebsolutions.com/test1

С setTimeout (): http://www.modwebsolutions.com/test2

Обратите внимание, что я изменяю только одну строку во всем сценарии, то есть строку 69:
без setTimeout (): vLoop();
с setTimeout (): setTimeout(vLoop,1);

Ответы [ 3 ]

3 голосов
/ 26 апреля 2011

Проблема, как намекают другие, заключается в том, что вы рисуете линии в квадранте за раз.Как только вызывается метод 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 );
}

В последнем блоке гарантируется, что квадранты не пересекаются друг с другом.

0 голосов
/ 24 апреля 2011

То, что происходит, это то, что 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);
});

Тогда это сработает (но это опасно, порядок не гарантирован!)

Рабочий пример можно посмотреть здесь .

0 голосов
/ 24 апреля 2011
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);

Вы вызываете 4 рекурсивных функции vLoop одновременно.Проблема в том, что setTimeout неблокирует, а рекурсия блокирует.Таким образом, теперь у вас есть все 4 функции drawVertical, которые работают параллельно, а не последовательно.

Другая проблема заключается в том, что все 4 ссылаются на глобальное состояние, и все ваши программные прерывания связаны с ними.

...