Опасно ли setTimeout / clearTimeout? - PullRequest
5 голосов
/ 17 ноября 2011

Я хотел бы спросить, существует ли другая реализация setTimeout / clearTimeout, чтобы заменить этот тип вложенной структуры, избегая обратной петли

function timedCount()
{
    document.getElementById('txt').value=c;
    c=c+1;
    t=setTimeout("timedCount()",1000);
}

function stopCount()
{
    clearTimeout(t);
    timer_is_on=0;
}

Я прочитал слишком опасно, чтобы иметь бесконечный вложенный цикл, потому что в неопределенный момент клиент потерпит крах из-за недостатка памяти.

Я тоже хочу спросить, что происходит с методом clearTimeout()? Очищает ли он стек памяти?

Ответы [ 4 ]

4 голосов
/ 17 ноября 2011

«рекурсивный» шаблон тайм-аута определенно не опасен (и не рекурсивен) сам по себе, но просто для уверенности используйте его так:

function timedCount()
{
    document.getElementById('txt').value=c;
    c=c+1;
    window.t=setTimeout( timedCount, 1000 );
}

function stopCount()
{
    clearTimeout(window.t);
    timer_is_on=0;
}

Это на самом деле более безопасно, чем setInterval, потому что, если в вызове setInterval происходит ошибка, он просто продолжает делать это снова и снова ...

(function updatePage(){
throw new Error( "computer is not turned on" );
setTimeout( updatePage, 1000 );
})()

function updatePageDumb(){
throw new Error( "computer is not turned on" );
}

setInterval( updatePageDumb, 1000 );
1 голос
/ 17 ноября 2011

Почему бы не использовать setInterval и clearInterval вместо этого?

0 голосов
/ 17 ноября 2011

Несколько указателей:

1) Поскольку вы пытаетесь получить доступ к элементу dom, лучше проверить, присутствует ли этот элемент в DOM.

Поскольку вы уже используете jQuery, желательно иметь весь этот код внутри $(document).ready().

2) clearTimeout удаляет ссылку t в этом случае из памяти, и любая последующая ссылка на нее приведет к непредсказуемым результатам. Переменная t фактически используется в случае, если вы хотите очистить timeout от элемента в какой-то момент.

3) Передача значения timedCount() в строковой форме означает, что JS придется применить eval, чтобы получить его значение, которое в данном случае относится к функции. http://www.jslint.org. Стандарты JS просят избегать использования eval. Здесь лучше использовать анонимную функцию, которая в свою очередь вызывает нужную функцию timedCount().

4) Что касается другой реализации, то это действительно зависит от того, как и когда вы хотите, чтобы ваша stopCount() функция вызывалась. В вашей реализации он фактически никогда не будет вызываться, поскольку он продолжает вызывать одну и ту же функцию после промежутка в 1 секунду.

желаемый код может быть что-то вроде

function timedCount()
{
    // the first 2 lines doing something
    t = setTimeout(function()
    {
        // if clear time out logic
        if ( can_clear_timeout() )
        {
            stopCount();
        }
        else
        {
            return timedCount();
        }
    }, 1000);
}

5) Еще одно предупреждение: нельзя использовать глобальные переменные, такие как timer_is_on, поскольку это противоречит стандартам.

0 голосов
/ 17 ноября 2011

setTimeout не является рекурсивным вызовом, он устанавливает внутренний таймер, который срабатывает один раз, а затем самоуничтожается. Вызов setTimeout заканчивается сразу после создания таймера, и поэтому функция завершается нормально. Поэтому ваш код должен работать нормально.

...