Задержка setTimeout не работает

Я пытаюсь обернуть голову вокруг setTimeout, но я не могу заставить его работать правильно.

Здесь я привел пример: http://jsfiddle.net/timkl/Fca2n/

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

Это мой HTML:

<a href="#">Click me!</a>

<span id="target"></span>

Это мой JS:

$(document).ready(function() {


function foo(){

    writeNumber = $("#target");

    setTimeout(writeNumber.html("1"),1000);
    setTimeout(writeNumber.html("2"),1000);
    setTimeout(writeNumber.html("3"),1000);
    };

$('a').click(function() {
 foo();
});

});

Любой намек на то, что я мог делать неправильно, очень ценится:)

Ответы

Ответ 1

setTimeout принимает функцию в качестве аргумента. Вы выполняете функцию и передаете результат в setTimeout (поэтому функция выполняется сразу). Вы можете использовать анонимные функции, например:

setTimeout(function() {
    writeNumber.html("1");
}, 1000);

Обратите внимание, что то же самое верно для setInterval.

Ответ 2

Вам нужно обернуть свои заявления анонимными функциями, а также пошатнуть тайминги -

setTimeout(function(){writeNumber.html("1")},1000);
setTimeout(function(){writeNumber.html("2")},2000);
setTimeout(function(){writeNumber.html("3")},3000);

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

Демо - http://jsfiddle.net/JSe3H/1/

Ответ 3

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

setTimeout(function() { writeNumber.html("1"); },1000);

Кроме того, вы хотите использовать другое значение задержки для каждого из них, чтобы таймеры не истекали одновременно. См. Обновленную скрипту в http://jsfiddle.net/RqCqM/

Ответ 4

Существует условие для передачи аргументов функции. В вашем случае вы можете сделать это с помощью

setTimeout(writeNumber.html,1000,1);
setTimeout(writeNumber.html,1000,2);
setTimeout(writeNumber.html,1000,3);

Третий аргумент функции setTimeout будет передан функции writeNumber.html

Ответ 5

Просто используйте setInterval(). Здесь, что я придумал. Вот ваш новый javascript:

function foo(){
    writeNumber = $("#target");
    number      = 0;
    writeNumber.html(number);
    setInterval(function(){
        number = number+1;
        writeNumber.html(number);
    },1000);
    };
$('a').click(function() {
 foo();
});

Ответ 6

Тебе нужно использовать функции, которые будут вызваны после передачи таймаута; вы также можете использовать анонимную функцию, тогда ваша функция foo будет выглядеть так:

function foo(){

writeNumber = $("#target");

setTimeout(function() { writeNumber.html("1"); },1000);
setTimeout(function() { writeNumber.html("2"); },1000);
setTimeout(function() { writeNumber.html("3"); },1000);

};

Ответ 7

Я приземлился на этот вопрос. На него ответили адекватно, и я думаю, что использование setInterval, поскольку предлагаемый @Purag, вероятно, лучший подход для получения желаемого функционального поведения. Однако исходный пример кода не учитывал асинхронное поведение JavaScript. Это часто встречающаяся ошибка, которую я сделал больше, чем когда-либо:).

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

setTimeout(function() {
    writeNumber.html("1");
    setTimeout(function() {
        writeNumber.html("1");
        setTimeout(function() {
            writeNumber.html("1");
        }, 1000);
    }, 1000);
}, 1000);

Теперь, конечно, это явно страшный код!

Я дал рабочий JSFiddle в свой собственный вопрос SO. Этот код иллюстрирует так называемую пирамиду doom. И это можно смягчить, используя JavaScript promises, как показано в ответах на мой вопрос. Требуется некоторая работа, чтобы написать версию WriteNumber(), которая использует promises, но тогда код может быть переписан в somehting, например:

writeNumAsync(0)
    .then(writeNumAsync)
    .then(writeNumAsync)
    .then(writeNumAsync);