Javascript setTimeout 延迟不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8196224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:03:51  来源:igfitidea点击:

setTimeout delay not working

javascriptjquerysettimeout

提问by timkl

I trying to wrap my head around setTimeout, but I can't get it to work properly.

我试图绕过我的头setTimeout,但我无法让它正常工作。

I have set up an example here: http://jsfiddle.net/timkl/Fca2n/

我在这里设置了一个例子:http: //jsfiddle.net/timkl/Fca2n/

I want a text to countdown after an anchor is clicked - but my setTimeoutseems to fire on the same time, even though I've set the delay to 1 sec.

我想要一个文本在点击锚点后倒计时 - 但我setTimeout似乎同时触发,即使我将延迟设置为 1 秒。

This is my HTML:

这是我的 HTML:

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

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

This is my JS:

这是我的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();
});

});

Any hint on what I could be doing wrong is highly appreciated :)

任何关于我可能做错的提示都非常感谢:)

回答by James Allardice

setTimeouttakes a function as an argument. You're executing the function and passing the result into setTimeout(so the function is executed straight away). You can use anonymous functions, for example:

setTimeout将函数作为参数。您正在执行该函数并将结果传递给setTimeout(因此该函数会立即执行)。您可以使用匿名函数,例如:

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

Note that the same is true of setInterval.

请注意,同样适用于setInterval

回答by ipr101

You need to wrap your statements in anonymous functions and also stagger your timings -

您需要将您的语句包装在匿名函数中并错开您的时间 -

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

If you set everything to 1000the steps will pretty much run simultaneously as the setTimeoutfunction will run the task 1 second after you called the function not 1 second after the previous call to the setTimeoutfunction finished.

如果您将所有内容都设置为1000步骤将几乎同时运行,因为该setTimeout函数将在您调用该函数后 1 秒运行任务,而不是在上一次调用该setTimeout函数完成后 1 秒。

Demo - http://jsfiddle.net/JSe3H/1/

演示 - http://jsfiddle.net/JSe3H/1/

回答by tvanfosson

You need to use a function referenceto be invoked later when the timer expires. Wrap each statement in an anonymous function so that it isn't executed immediately, but rather when the timer expires.

您需要使用稍后在计时器到期时调用的函数引用。将每个语句包装在一个匿名函数中,以便它不会立即执行,而是在计时器到期时执行。

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

Also, you want to use a different delay value for each one so that the timers don't expire at the same time. See an updated fiddle at http://jsfiddle.net/RqCqM/

此外,您希望为每个延迟值使用不同的延迟值,以便计时器不会同时到期。在http://jsfiddle.net/RqCqM/查看更新的小提琴

回答by Irvin Dominin

You need tot use a functions to be called after the timeout is passed; you can use anonymous function too, then your function foo will look like this:

您需要在超时后使用要调用的函数;您也可以使用匿名函数,那么您的函数 foo 将如下所示:

function foo(){

writeNumber = $("#target");

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

};

回答by Achal Saraiya

There is a provision to pass arguments to the function. In your case, you can do it by

有一个规定可以将参数传递给函数。在你的情况下,你可以通过

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

third argument to setTimeout function will be pass to writeNumber.html function

setTimeout 函数的第三个参数将传递给 writeNumber.html 函数

回答by Purag

Just use setInterval(). Here's what I came up with. Here's your new javascript:

只需使用setInterval(). 是我想出的。这是您的新 javascript:

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

回答by Bart

I landed on this question. It has been answered adequately, and I think using setIntervalas @Purag suggested is probably the best approach to get the desired functional behaviour. However the initial code example did not take JavaScript's asynchroneous behaviour into account. This is an often occurring error, which I've made myself on more than occasion :).

我登陆了这个问题。它已经得到了充分的回答,我认为setInterval按照@Purag 的建议使用可能是获得所需功能行为的最佳方法。然而,最初的代码示例没有考虑 JavaScript 的异步行为。这是一个经常发生的错误,我不止一次犯过这个错误:)。

So as a side note I wanted to give another possible solution for this which mimics the initial attempt, but this time DOES consider Javascript's Asynchronousity:

所以作为旁注,我想为此提供另一个可能的解决方案,它模仿最初的尝试,但这次确实考虑了 Javascript 的异步性:

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

Now ofcourse this is clearly terrible code!

现在当然这显然是糟糕的代码!

I have given a working JSFiddle of it in my own SO question. This code exemplifies the so-called pyramid of doom. And this can be mitigated by using JavaScript promises, as shown in the answers to my question. It takes some work to write a version of WriteNumber()that uses Promises, but then the code can be rewritten to somehting like:

我在我自己的 SO 问题中给出了一个有效的 JSFiddle 。这段代码体现了所谓的厄运金字塔。这可以通过使用 JavaScript 承诺来缓解,如我的问题的答案所示。编写一个WriteNumber()使用 Promises的版本需要一些工作,但随后可以将代码重写为以下内容:

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