Как я могу заставить мои функции setTimout работать с той же скоростью? - PullRequest
7 голосов
/ 27 января 2012

Предисловие: У меня есть демонстрационная версия проблемы на моем личном сайте (надеюсь, это нормально. Если нет, я могу попытаться настроить ее на jsfiddle).Я хочу, чтобы этот вопрос был немного забавным, и в то же время пытаюсь понять, как функции времени используют javascript.

Я увеличиваю значение индикаторов выполнения по таймауту.В идеале (если функции запускаются мгновенно) они должны заполнять с той же скоростью, но в реальном мире - нет.Код такой:

function setProgress(bar, myPer) {
bar.progressbar({ value: myPer })
    .children('.ui-progressbar-value')
        .html(myPer.toPrecision(3) + '%')
            .attr('align', 'center');
    myPer++;
    if(myPer == 100) { myPer = 0; }
 }

 function moveProgress(bar, myPer, inc, delay){
    setProgress(bar, myPer);
    if(myPer >= 100) { myPer = 0; }
    setTimeout(function() { moveProgress(bar, myPer+inc, inc, delay); }, delay);
 }

 $(function() { 
   moveProgress($(".progressBar#bar1"), 0, 1, 500);
   moveProgress($(".progressBar#bar2"), 0, 1, 500);
   moveProgress($(".progressBar#bar3"), 0, .1, 50);
   moveProgress($(".progressBar#bar4"), 0, .01, 5);             
 });

Наивно можно подумать, что все должны работать (заполнять индикатор выполнения) с одинаковой скоростью.

Однако в первых двух барах (если мы называем «установка индикатора выполнения» одной операцией), я выполняю одну операцию каждые 500 мс, всего 500 операций для заполнения бара;в-третьих, я выполняю одну операцию каждые 50 мс, в общей сложности 5000 операций, чтобы заполнить планку;в четвертом я выполняю одну операцию каждые 5 мс, чтобы в общей сложности 50 000 операций заполнили планку.

Какая часть моего кода занимает больше всего времени, вызывает эти различия в скорости и может быть изменена по порядкучтобы заставить их функционировать так же, как они (четвертый столбец получает меньшие приращения), но также работать с той же скоростью?

Ответы [ 3 ]

3 голосов
/ 27 января 2012

Самая большая проблема с использованием setTimeout для подобных вещей заключается в том, что выполнение вашего кода происходит между тайм-аутами и не учитывается в значении, отправляемом setTimeout. Если ваша задержка составляет 5 мс, а выполнение вашего кода занимает 5 мс, вы существенно удваиваете время.

Еще одним фактором является то, что после срабатывания таймаута, если другой фрагмент кода уже выполняется, он должен будет дождаться его завершения, что задержит выполнение.

Это очень похоже на проблемы, возникающие у людей при попытке использовать setTimeout для часов или секундомера. Решение состоит в том, чтобы сравнить текущее время со временем запуска программы и рассчитать время на основе этого. Вы могли бы сделать что-то подобное. Проверьте, сколько времени прошло с тех пор, как вы начали, и установите%, основываясь на этом.

0 голосов
/ 27 января 2012

Мне нравится вопрос, у меня нет очень точного ответа, но вот мои 2 цента:

Javascript - это очень быстрый язык, который отлично справляется со своим циклом событий и поэтому ест setTimeouts и setIntervals на завтрак.
Однако существуют ограничения, и они зависят от большого числа факторов, таких как скорость браузера и компьютера, количество функций, которые у вас есть в цикле событий, сложность кода для выполнения и значения времени ожидания ...

В этом случае, я думаю, очевидно, что если вы попытаетесь выполнить одну функцию каждые 500 мс, она будет вести себя намного лучше, чем ее выполнение каждые 50 мс, поэтому намного лучше, чем каждые 5 мс. Если принять во внимание, что вы запускаете их все друг на друга, вы можете предсказать, что производительность не будет оптимальной.

Вы можете попробовать это упражнение:
возьмите 500 мс и запустите его в одиночку. отметьте общее время заполнения бара (здесь вы увидите, что это займет немного больше времени, чем предполагалось).
попробуйте выполнить два тайм-аута по 500 мс одновременно и убедитесь, что общее время стало немного больше.
Если вы добавите 50 мс, а затем 5 мс, вы увидите, что вы будете терять производительность каждый раз ...

0 голосов
/ 27 января 2012

Что вызывает разницу в скорости две вещи: во-первых, это тот факт, что вы выполняете больше кода, чтобы заполнить нижнюю строку (как вы упоминаете во втором абзаце). Кроме того, каждый раз, когда вы устанавливаете тайм-аут, ваш браузер ставит его в очередь ... фактическая задержка может быть дольше, чем вы указываете, в зависимости от того, сколько в очереди (см. MDN в window.setTimeout ) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...