Может ли что-то прервать время setTimeout? - PullRequest
0 голосов
/ 03 апреля 2020

Как запустить функцию Javascript в интервале, который начинается в конце выполнения обратного вызова?

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

Теперь время от времени наблюдается странное поведение. Я изо всех сил пытаюсь диагностировать это.

Я вставляю свою функцию внизу. Вам не нужно читать все это. Функция выполняет аудиозапись цифр и после выдачи подсказки, которая останавливает выполнение, а после ответа пользователя происходит пятисекундный тайм-аут, после которого функция запускается снова. Чаще всего он работает нормально, однако через несколько раз после большего выполнения он начинает работать все ближе и ближе, время ожидания сокращается с 5 секунд почти до нуля. Это происходит не во всех контекстах, поэтому я не думаю, что что-то не так в функции, которую я опубликовал. Мой вопрос: что может изменить это расписание в стеке вызовов? Некоторый другой код, который выполняется, может задержать запуск функции (я мог бы жить с этим), однако следующий вызов все равно должен начаться через 5000 мс после того, как он будет выполнен после окончания аудио.

Я сделал не включайте весь другой код, который выполняется одновременно, потому что его слишком много.

function myTimer() {
    var auditoryRoundNumber = gorilla.retrieve("auditoryRoundNumber", 0);
    console.log("arn "+auditoryRoundNumber);
    const queue = [];
    var two_back=gorilla.retrieve("two_back", queue);

    if(auditoryRoundNumber<2){
        //console.log(auditoryRoundNumber);
        randint= Math.floor(Math.random() * 10);
    }else{
        //after the first two trials we assign a higher probability to the digit that happen two trials ago.

        //We make a draw in 50% of the cases it is a random digit in the other 50% it is the two back
        var draw=Math.random();
        if(draw>0.5){
            randint= Math.floor(Math.random() * 10);
        }else{
            randint= two_back[0];
            //console.log(randint);
        }
    }
    two_back.push(randint);
    randstimuli=gorilla.stimuliURL(mdict[randint]);
    //console.log(randstimuli);
    var audio = new Audio(randstimuli);
    audio.play();
    //var interval=5000;//(audioInterval=="Fixed") ? 5000 : Math.floor(Math.random() * 5000)+1000;

    audio.onended=function(){
        auditoryRoundNumber=auditoryRoundNumber+1;
        gorilla.store("auditoryRoundNumber",auditoryRoundNumber);
        //In the first two trial we do not ask what is the number two steps ago.
        if(auditoryRoundNumber>2){
            var start=Date.now();
            var ans=prompt("Was the last number the same as the one two steps ago? Y-Yes/N-No");
            ans=input_validation(ans);
            //console.log(two_back.length); 
            ans=(ans=="y"||ans=="Y")? 1: 0;
            //We remove the first item from the queue other items get reindexed
            two_back_ans= two_back.shift();
            //console.log(two_back_ans+" "+ (ans==two_back_ans)? 1:0);
            gorilla.metric({
                current_int: randint,
                two_back_int: two_back_ans,
                response_audio: ans,
                audio_correct: (ans==(randint==two_back_ans))? 1:0,//expressions to evaluate similarity between ans and 2-back
                audio_RT: Date.now()-start
            });
            //console.log(auditoryRoundNumber);

            if(auditoryRoundNumber>= NoOfAudioTrials+2){
                return;
            }
        }else{
            gorilla.metric({
                current_int: randint,
            });
        }
        gorilla.store("two_back", two_back);
        task_id=setTimeout(myTimer,5000);
    }
}
...