Задержка setTimeout не работает - PullRequest
17 голосов
/ 19 ноября 2011

Я пытаюсь обернуть голову вокруг 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();
});

});

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

Ответы [ 7 ]

42 голосов
/ 19 ноября 2011

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

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

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

5 голосов
/ 19 ноября 2011

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

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/

2 голосов
/ 04 ноября 2016

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

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

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

2 голосов
/ 19 ноября 2011

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

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

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

1 голос
/ 19 ноября 2011

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

function foo(){

writeNumber = $("#target");

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

};
1 голос
/ 19 ноября 2011

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

function foo(){
    writeNumber = $("#target");
    number      = 0;
    writeNumber.html(number);
    setInterval(function(){
        number = number+1;
        writeNumber.html(number);
    },1000);
    };
$('a').click(function() {
 foo();
});
0 голосов
/ 04 декабря 2014

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

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

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

Конечно, это явно ужасный код!

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

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