Задержка 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);