Защо setTimeout изисква анонимна функция, за да работи?

Четох отговор на StackOverflow тук, който обясняваше как да използвам setTimeout за създаване на нещо като повтарящ се цикъл на уеб страница. Чудя се обаче защо setTimeout изисква анонимна функция, за да работи. Разгледайте следния код:

trainingTimer(60,0);

function trainingTimer(duration,c) {
    document.getElementById("timer").innerHTML = "Time left: "+(duration-c);
    if(duration==c) {
        alert("Time is up!");
    }
    else {
        window.setTimeout(trainingTimer(duration,c+1),1000);
    }
}

Написах това въз основа на отговора, който свързах по-горе, но когато се изпълнява, преминава през всичките 60 trainingTimer повиквания наведнъж и веднага показва „Оставащо време: 0“ на моята уеб страница. Ако обаче модифицирам

window.setTimeout(trainingTimer(duration,c+1),1000);

и обвийте trainingTimer(duration,c+1) в анонимна функция по този начин

window.setTimeout(function() {trainingTimer(duration,c+1)},1000);

тогава кодът работи перфектно.

Чудя се защо трябва да обвивам функция с име в анонимна функция, за да може setInterval да работи правилно. Благодаря за цялата помощ.


person Charles    schedule 13.05.2014    source източник
comment
trainingTimer(someargs) не връща функция и setTimeout се нуждае от функция за изпълнение.   -  person Kevin B    schedule 14.05.2014
comment
@KevinB Технически не се нуждае от функция...   -  person epascarello    schedule 14.05.2014
comment
предполагам, че window.alert() не се нуждае от аргумент.   -  person Kevin B    schedule 14.05.2014
comment
Повече за редовете, че може да вземе низ и да го оцени.   -  person epascarello    schedule 14.05.2014


Отговори (3)


Това

window.setTimeout(trainingTimer(duration,c+1),1000); 

е същото като

var result = trainingTimer(duration,c+1);
window.setTimeout(result,1000); 

Той взема резултата от изпълнения метод и го присвоява.

И тъй като методът на таймера за обучение не връща нищо. Вашият код е основно това

trainingTimer(duration,c+1);
window.setTimeout(undefined, 1000); 
person epascarello    schedule 13.05.2014

Средата за изпълнение трябва да оцени списъка с аргументи, подаден на която и да е функция преди да извика функцията. Първото нещо, което предавате на setTimeout в този код:

window.setTimeout( trainingTimer(duration,c+1), 1000 );

е резултат от извикване на функция, а не самата функция. Обвиването на това във функция решава този проблем.

Функцията не трябва да е анонимна:

function callTrainingTimer() {
    trainingTimer( duration, c + 1);
}

// ...

window.setTimeout(callTrainingTimer, 1000);

работи също.

person Pointy    schedule 13.05.2014

Защото така работи setTimeout. Първият му параметър е функция, която искате да изпълни след x милисекунди.

Когато направите:

window.setTimeout(trainingTimer(duration,c+1),1000);

Това, което правите, е да изпълните trainingTimer незабавно и да изпратите върнатата му стойност до setTimeout.

Трябва да му дадете функция, затова правите:

window.setTimeout(function() {
    trainingTimer(duration, c+1);
},1000);

Има има начин да го направите без функция, но НЕ се препоръчва.

window.setTimeout('trainingTimer(duration,c+1)', 1000);

Това ще използва eval() за изпълнение на кода. Това работи вместо предаване на функция, но не се препоръчва. eval() не е безопасно, не го използвайте.

person Rocket Hazmat    schedule 13.05.2014