Проблемы с производительностью при вызове setTImeout по-разному

Рассмотрим следующий блок кода

var interval = setTimeout(function()
    {

        var left = parseInt(self.element.style.left) - 10;
        var width = parseInt(self.element.style.width) + 10;

        if(width <= self.width)
        {

            self.element.style.left = left + "px";
            self.element.style.width = width + "px";
            setTimeout(increaseWidthLeft(self), 10);

        }
        else
        {

            window.clearInterval(interval);

        }

    }, 5);

И этот:

var interval = setTimeout(function()
    {

        var left = parseInt(self.element.style.left) - 10;
        var width = parseInt(self.element.style.width) + 10;

        if(width <= self.width)
        {

            self.element.style.left = left + "px";
            self.element.style.width = width + "px";
            setTimeout(function(){increaseWidthLeft(self);}, 10);

        }
        else
        {

            window.clearInterval(interval);

        }

    }, 5);

Они почти одинаковые да? Но когда я запускаю первую версию, "анимация" работает с ошеломляющей скоростью... однако вторая работает почти в 3 раза медленнее первой. Что здесь происходит? Любая помощь очень ценится


person lauCosma    schedule 16.12.2013    source источник
comment
Я не уверен, имеет ли это какое-либо отношение к вашей проблеме, но вы устанавливаете Timeout и очищаете Interval. Вы должны использовать clearTimeout(). clearInterval() и clearTimeout() не взаимозаменяемы. Дополнительные сведения см. в этом ответе.   -  person War10ck    schedule 16.12.2013
comment
Спасибо что подметил это.   -  person lauCosma    schedule 17.12.2013
comment
Для любых будущих посетителей способ определения спецификаций W3C делает так, что clearInterval и clearTimeout взаимозаменяемы. По-прежнему хорошо использовать правильный для удобочитаемости кода, но с точки зрения функциональности они должны делать то же самое. stackoverflow.com/questions/9913719/   -  person Steve    schedule 12.07.2018


Ответы (1)


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

Чрезвычайно тонкие различия между версиями кода заключаются в использовании анонимной функции во втором примере по сравнению с простой предопределенной функцией в первом.

Когда вы запускаете setTimeout(increaseWidthLeft(self), 10);, javascript делает именно то, что вы ожидаете. Он запускается increaseWidthLeft(self) после завершения задержки. Очень прямо вперед.

Когда вы запускаете function(){increaseWidthLeft(self);}, фактически создается функция, которая затем запускает increaseWidthLeft(self). Как только эта функция завершается, она удаляется только для того, чтобы снова создаться в следующем цикле. Именно эти накладные расходы на создание должны замедлять код.

Есть смысл в том, что второй будет работать медленнее, хотя, признаюсь, я удивлен, что это было так заметно. Тем не менее, полезная информация, если вам когда-нибудь понадобится повысить точность тайм-аута.

К сожалению, ничего из этого не относится к моей проблеме, поэтому я продолжу свою охоту. ;)

person Steve    schedule 12.07.2018