Javascript - несколько settimeouts в цикле - PullRequest
0 голосов
/ 02 февраля 2012

Я хочу прочитать файл, кое-что сделать, проверить режим действия.

Если mode = STOP, отложить обработку до режима! = STOP, в противном случае повторить весь процесс.

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

Приведенный ниже код приводит к бесконечному циклу и сбою браузера:

function fnIterateGeocode(addressVariations) {

    // read a file & do some stuff  

    // check for delay
    fnDelay();

   // if not end of file then Iterate
   if (nextRecord.EOF != 'Y') {
        setTimeout(function(){                      
            fnIterateGeocode(addressVariations);                        
        }
        , 5000);
    }


    // if mode = STOP, then delay for 5 seconds and check again     

    function fnDelay(){
        if(mode == 'STOP'){
                setTimeout(function(){                                                      
                }
                , 5000);
                fnDelay();
        }
        return;
    }           

    return;
}

Ответы [ 2 ]

2 голосов
/ 02 февраля 2012

Вы перевели вызов fnDelay в неправильном месте:

function fnDelay(){
    if(mode == 'STOP'){
            setTimeout(function(){
                // It should be here
            }
            , 5000);
            fnDelay(); // Not here
    }
    return;
}

То, как ваш код написан на текущий момент, действительно представляет собой бесконечный цикл (ну, это было бы, если бы вы не исчерпали пространство стека), потому что fnDelay всегда вызывает себя немедленно.

0 голосов
/ 02 февраля 2012

Не думаю, что вы полностью понимаете асинхронный код.

Нет способа «задержать» JavaScript, как вы пытаетесь (например, wait или sleep на других языках). Вызов setTimeout не останавливает выполнение в этот момент в течение 5 секунд.

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

В вашем примере, что-то вроде следующего имело бы больше смысла:

function fnDelay(){
    if(mode != 'STOP'){ fnIterateGeocode(); }
    else { setTimeout(fnDelay,5000);
}

Это будет вызывать себя каждые 5 секунд, пока mode == 'STOP', как только это не произойдет, оно будет вызывать fnIterateGeocode.

...