2015-04-05 2 views
0

У меня есть функция в JavaScript. Я использую setInterval, чтобы контролировать свою функцию. У меня также есть другая логика для управления моей функцией. У меня есть счетчик, который увеличивается, когда происходит одно условие, и уменьшается при возникновении другого состояния. Теперь, иногда второго условия не происходит, и, следовательно, моя функция больше не будет возобновлена. (Я приостанавливаю свою функцию, когда происходит первое условие). Поэтому я хочу подождать не более 30 секунд для второго условия. Если этого не произойдет, то я все равно хочу возобновить свою функцию. У меня есть следующий код, но он не работает, как я ожидаю. Случается, что он возобновляет мою функцию каждые 30 секунд. Затем он может быть возобновлен, пока он должен ждать. Может ли кто-нибудь сообщить мне, в чем проблема с моим кодом?Определить таймер в JavaScript

Обратите внимание, что значение счетчика может увеличиться более чем до 20. Я имею в виду, что первое и второе условие может происходить более одного раза.

function main() 
{ 
    // body 
} 

function increaseCounter() 
{ 
    counter += 1; 

    clearInterval(controller); 
    controlSecond = setInterval(function(){ 
     counterSeconds += 1; 
     if (counterSeconds == 30) 
     { 
      counterSeconds = 0; 

      controller = setInterval(main, 100); 
      clearInterval(controlSecond); 
     } 
    }, 1000); 
} 

function decreaseCounter() 
{ 
    counter -= 1; 

    if (counter == 0) 
    { 
     counterSeconds = 0; 
     clearInterval(controlSecond); 

     controller = setInterval(main, 100); 
    } 
} 
+0

Как называются эти 2 функции? Можете ли вы создать простую демонстрацию через jsfiddle? – Joseph

+0

Честно говоря, это немного сложно, так как это небольшая часть моего большого проекта! На самом деле я использую PhantomJS, и эти две функции - две из его функций обратных вызовов. – Suo6613

+1

Вы должны поставить 'clearInterval (x);' прямо перед каждым оператором 'x = setInterval (...)'. – Wio

ответ

0

Почему не

var counter = 0 
var timeout = null 

function main() { 
    clearTimeout(timeout); 
    timeout = null; 
} 

function increaseCounter() { 
    counter++; 
    if (!timeout) 
     timeout = setTimeout(main, 30*1000); 
} 

function decreaseCounter() { 
    counter--; 
    if (counter === 0) 
     main(); 
} 
2

Рассмотрим, что произойдет, если вы звоните increaseCounter дважды подряд.

При первом выполнении он создаст интервал A и назначит его controlSecond.

На втором выполнении это создаст интервал B и присвоить его controlSecond, а интервал Д продолжает стрелять на неопределенный срок. Вы не остановите его с clearInterval(controlSecond), потому что controlSecond больше не ссылается Интервал A.

Проблема в том, что вы продолжаете устанавливать controlSecond и controller на новый интервал, не очищая их в первую очередь. Это приводит к утечке интервалов без возможности их очистки. Это похоже на утечку памяти, когда у вас есть динамически распределенная память, но на нее ничего не указывалось, но вместо ренегатной памяти у вас есть интервалы ренегата.

Один из способов предотвратить это - убедиться, что вы всегда очищаете свой интервал перед его настройкой.

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

+0

Я правильно понимаю вашу точку зрения! Но я не хочу использовать 'setTimeout', потому что я хочу, чтобы мои функции возобновились в то время, когда они были готовы. Но, используя 'setTimeout', я должен ждать пример в течение 3 секунд каждый раз. Это было бы слишком для некоторых действий и, возможно, меньше для некоторых других. Как я могу «очистить» мой «интервал», прежде чем устанавливать их снова? – Suo6613