2013-05-14 2 views
0

Я пытаюсь запустить последовательные таймеры обратного отсчета, но не могу понять, как дождаться окончания таймера, прежде чем перейти к следующему элементу.Looping Javascript timer

for(var i = 0; i < 5; i++) 
{ 
    var count = 5; 
    var counter = setInterval(timer, 1000); 
} 

function timer() 
{ 
    count--; 
    if (count <= 0) 
    { 
     $('.workout-timer').text(count + "secs"); 
     clearInterval(counter); 
     return; 
    } 

    $('.workout-timer').text(count + "secs"); 
} 

Это просто идет отрицательно, однако без цикла for код отсчитывается от 5 до 0 просто отлично. Итак, мой вопрос: как получить несколько обратных отсчетов один за другим? Не подходит ли таймер для этого?

+0

Не создавайте 5 интервалов. Создайте один (без цикла). – user2246674

+0

Почему бы не использовать 'setTimeout'? – akonsu

+0

@ user2246674 Что это значит? – akonsu

ответ

1

Вы могли бы сделать что-то вроде этого:

function startCountdown(count, delay, callback) { 
    if (!count) { 
     callback && callback(); 
     return; 
    } 

    //do something here 
    console.log(count); 

    setTimeout(function() { 
     startCountdown(--count, delay, callback); 
    }, delay); 
} 

startCountdown(5, 1000, function() { 
    startCountdown(5, 1500); 
}); 

Однако это может запутаться, если у вас есть много вложенных обратных вызовов, но вот один из многих подход можно использовать для решения этого вопроса:

var queue = [ 
     { count: 5, delay: 1000 }, 
     { count: 10, delay: 200 }, 
     { count: 5, delay: 5000 } 
    ]; 

processNextCountdown(); 

function processNextCountdown() { 
    var options = queue.shift(); 

    if (options) { 
     startCountdown(options.count, options.delay, processNextCountdown); 
    } 
} 
+0

Зачем использовать таймаут в течение интервала? – user2246674

+0

, потому что вам не нужно его отменять. – akonsu

+0

@akonsu .. так? Вам нужно создать только один интервал. – user2246674

1

Intervals - как таймауты, которые будут перенести себя (что differs с таймаутом, начиная новый таймаут). Поскольку интервалы перепланируют сами, создать только один. (Или, только столько, сколько действительно необходимо.)

Проблемы с оригинальным постом он создавал интервалов (потому что они были созданы в цикле), а затем только сохраняя интервал ID (в counter) от последнего интервала! Таким образом, clearInterval остановился только последний интервал и остальные 4 интервалов продолжал работать и работает, и работает ..

Вот некоторые очистке кода с комментариями и без исходной задачи:

var count = 5; 
// only need ONE interval 
var counter = setInterval(timer, 1000); 
// so we do one count RIGHT NOW 
timer(); 

function timer() { 
    // display first, so we start at 5: 5, 4 .. 1 
    console.log(count); 
    count--; 
    if (count < 0) { 
    // to repeat the count, comment out the clearInterval 
    // and do `count = 5;` or similar .. take it from here :D 
    clearInterval(counter); 
    } 
} 

Чтобы создать отдельный " state "для каждого обратного отсчета, либо создайте новый объект обратного отсчета, который сохраняет состояние в свойствах, либо use a closure. Вот пример с закрытием. Я также добавил поддержку функции обратного вызова, чтобы показать, как такая функция может быть более общее:

function makeCountdown(startCount, delay, fn) { 
    fn = fn || function (i) { 
     // default action, if fn not specified 
     console.log(i); 
    }; 
    // local variables 
    var count = startCount; 
    var counter = setInterval(timer, delay); 
    timer(); 

    function timer() { 
     // now count and counter refer to variables in the closure (keyword!) 
     // which are different each time makeCountdown is called. 
     fn(count); 
     count--; 
     if (count < 0) { 
      clearInterval(counter); 
     } 
    } 
} 

makeCountdown(20, 500); // uses default function 
makeCountdown(10, 1000, function (i) { console.log(10 - i) }); 
makeCountdown(5, 2000, function (i) { console.log("SLOW! " + i) }); 

упражнение:

  1. Добавить функцию обратного вызова для того, когда обратный отсчет «сделан», так что обратные отсчеты могут запускаться последовательно.
  2. Используйте генератор серий и используйте его для генерации следующего значения count.
  3. Иметь makeCountdown вернуть объект, который может использоваться для управления обратным отсчетом.
  4. Удачи!
+0

, это не касается проблемы, которую я имею, я на самом деле пытаюсь получить 5 отдельных обратных отсчетов, которые происходят после другой – user975044

+0

@ user975044 Обновлен с примером, который использует замыкания для запоминания переменных «count» и «counter» для каждого интервала. – user2246674

+0

@ user975044 Это может стать как забавным/сложным/общим по мере необходимости. jQuery имеет реализацию очереди для работы с анимацией - например. переместите левый 20, затем погасните – user2246674