【问题标题】:setTimeout delay doesn't wait for the timeoutsetTimeout 延迟不等待超时
【发布时间】:2011-11-19 18:26:56
【问题描述】:

我试图绕过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();
});

});

【问题讨论】:

    标签: javascript jquery settimeout


    【解决方案1】:

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

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

    请注意,setInterval 也是如此。

    【讨论】:

    • 感谢您帮助我! :) 我更新了我的 jsfiddle:jsfiddle.net/timkl/cRDQh 我仍然得到相同的结果,同时触发了 setTimeouts。
    • 没问题 :) 如果您不希望它们同时触发,请更改超时长度。例如,第一次超时 1000 毫秒,第二次超时 2000 毫秒,依此类推。
    • 这不仅适用于setTimeoutsetInterval,而且对于每种情况,您都应该将回调作为参数之一传递。
    • @Tadeck - 是的,好点。除了在执行函数时返回一个函数:)
    • @JamesAllardice:同意,但在这种情况下,您仍在传递回调(即使它是执行另一个函数的结果)。它变得更加复杂,但线索是传递一个函数,我们希望在指定时间段(或给定时间间隔)之后执行,而不是在传递时执行它。
    【解决方案2】:

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

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

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

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

    【讨论】:

    • +1 好点 - 您不仅指出了回调的传递方式,还指出了它的执行时间。
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      function foo(){
      
      writeNumber = $("#target");
      
      setTimeout(function() { writeNumber.html("1"); },1000);
      setTimeout(function() { writeNumber.html("2"); },1000);
      setTimeout(function() { writeNumber.html("3"); },1000);
      
      };
      

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

          只需使用setInterval()Here 是我想出的。这是你的新 JavaScript:

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

          【讨论】:

            【解决方案7】:

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

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

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

            当然,这显然是很糟糕的代码!

            我在my own SO question 中给出了一个有效的JSFiddle。这段代码举例说明了所谓的厄运金字塔。这可以通过使用 JavaScript 承诺来缓解,如我的问题的答案所示。编写一个使用 Promises 的 WriteNumber() 版本需要一些工作,但是代码可以重写为:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-01-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多