【问题标题】:How to use jQuery's delay() as a sleep()?如何使用 jQuery 的 delay() 作为 sleep()?
【发布时间】:2010-07-30 22:57:27
【问题描述】:

jQuery 可以用作 sleep() 或 wait() 函数吗?等待后暂停语句的执行。我尝试了 $().delay(5000) 但没有等待 5 秒。 delay() 只用在效果器中吗?

我不是在寻找涉及 setTimeout 延迟执行另一个函数或占用 CPU 的解决方案的解决方案。我想要一个可以在不同脚本中重复使用的 sleep() 函数。

加法:

我并不是要建议一个根本不使用 setTimeout 的解决方案。我已经看到了需要在需要延迟之后将所有代码移动到自己的函数中的解决方案,以便 setTimeout 可以调用它。我不想要那个。使用 setTimeout 的自包含包装函数或在虚拟非视觉效果中使用 jQuery delay() 只是为了模拟睡眠函数。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    你会倒霉的。任何sleep() 函数很可能需要使用setTimeout(或者可能是setInterval)。事实上,delay() 本身使用了setTimeout。来自 jQuery 1.4.2 来源:

    delay: function( time, type ) {
        time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
        type = type || "fx";
    
        return this.queue( type, function() {
            var elem = this;
            setTimeout(function() {
                jQuery.dequeue( elem, type );
            }, time );
        });
    },
    

    .delay() 仅适用于效果使用的队列(fx 队列)。可以通过.queue()使用自定义队列

    【讨论】:

    • 我见过的最接近的是 Ben Alman 的 doTimeout 插件 - benalman.com/projects/jquery-dotimeout-plugin 但即使这样,以下链式方法的执行也不会因传递给 doTimeout 方法的时间间隔而延迟打电话。
    【解决方案2】:

    这对我来说非常有用:

    http://benalman.com/projects/jquery-dotimeout-plugin/

    $.doTimeout(3000,function(){
        alert('yahoooooo!');
    });
    

    例子:

    http://benalman.com/code/projects/jquery-dotimeout/examples/delay-poll/

    【讨论】:

      【解决方案3】:

      Javascript(以及扩展,jQuery)没有真正的“睡眠”功能。您可以或多或少地滥用 setTimeout 和 setInterval(以及它们的衍生物,如延迟)来模拟睡眠,但您通常最好只适应 setInterval/Timeout 的做事方式......弄清楚你想要做什么,密封它在一个函数中关闭,将它作为参数传递给这两个之一。

      编辑:

      好的,我看到你的编辑了。你真的想要一个传统的睡眠功能。接下来是绝对滥用,而不是我推荐的。但如果我必须建造一个来挽救我的生命,我会这样做:测试大量循环周期需要多长时间,进行统计上显着数量的这些测试,平均结果,并使用该信息来定义一个函数,将给定的毫秒数大致转换为多个循环周期,然后运行。

      在 JavaScript 中:

      function timeloop(cycles) { 
          var start = new Date().getTime(); 
          for(var j=0; j<cycles; j++); 
          var end = new Date().getTime(); 
          return end-start; 
      }
      
      
      var sleep = (function () {
          var ms_tally = 0, i, s = 100, L = 10000;
      
          for(i=0; i<s; i++) 
              ms_tally += timeloop(L);
          var avg = ms_tally / i;
          var ms_per_cycle = avg / L;
          var cycles_per_ms = 1 / ms_per_cycle;
      
          return eval('function (ms) { for(var k=0, z=ms*'+cycles_per_ms+'; k<z; k++); }');
      })()
      

      不过,我不会相信我的生命、健康,甚至 20 美元的时间准确性。如果您需要小于半秒的任何精度,在 JavaScript 中执行此操作的正确方法是信任内置于您正在使用的任何环境中的工具......在浏览器中,这就是 setInterval 和 setTimeout。

      编辑#2:

      我在其中一个 cmets 中看到了对 Ben Alman's doTimeout plugin 的推荐。看完之后,值得注意的是,它比我在上面制作的可憎之物几乎在所有方面都更好。这不是我们经常习惯的舒适的sleep-y 语法相当,您仍然需要以某种边缘方式考虑函数中的代码,但至少您仍然可以保持顺序的感觉。如果您不能让自己直接使用 setTimeout/Interval,请使用 doTimeout 或类似的东西。

      【讨论】:

      • 它不存在,克服它,使用 setTimeout!
      • 好的,作为练习,我添加了一个常规的sleep,但是......如果时间很重要,请不要使用它。
      • 如果这会阻止浏览器后台进程运行,它对我不起作用。
      • 这取决于浏览器。我认为他们中的大多数都有每个 JavaScript 上下文执行它自己的线程,这意味着理论上其他事情仍然可以发生。不过,在实践中,我已经看到处理器咀嚼 JS 锁定了浏览器,我相信其他人也有。我认为 doTimeout 之类的东西将是你能找到的最接近实际的、感觉有顺序的解决方案。
      • 我已经使用了我找到的所有实现,但没有一个能正常工作。所以我正在使用 setTimeout 并拆分我的代码。
      【解决方案4】:

      如果你不想占用 CPU 时间,你将不得不以某种方式使用 setTimeout 或类似的东西。

      这是一个例子:

      function myfn() {
          // make it so that `myvar` is in scope and can 
          // be shared by both `fn1` and `fn2`
          var myvar
      
          function fn1() {
              alert('foo')
              // set `bar` in the above `myfn`'s scope (without `var`)
              myvar = 'bar'
              // sleep for 1.2 seconds
              setTimeout(fn2, 1200)
          }
      
          function fn2() {
              alert(myvar)
          }
          fn1()
      }
      myfn()
      

      【讨论】:

        【解决方案5】:

        根据您的问题 如何使用jQuery的delay()作为sleep()?,回答这个问题:

        我尝试了 $().delay(5000) 但没有等待 5 秒。是延迟() 只用在效果器中?

        您是否已经尝试过带有 delay() 的 jQuery.queue()? 例如

        $.fn.extend({
            changeBgColor: function(color) {
                return this.each(function() {
                  $(this).css("background-color", color);
                });
            }
        });
        $.fn.wait = function(mls, callback) {   
            return this.delay(mls).queue(function () {
              $("span").text($(this).queue().length);    
              callback();    
              $(this).dequeue();
            });    
        };
        
        $(document).ready(function(){
            $("#start").click(function(){
                var div = $("div");        
        
                div.delay(1000).queue(function () {
                    $("span").text(div.queue().length);
                    div.css("background-color", "red").text("red");
                    $(this).dequeue();
                }).delay(1000).queue(function (next) {
                    $("span").text(div.queue().length); 
                    div.changeBgColor("green").text("green");
                    next();
                });
        
                div.wait(1000,function () {       
                    div.changeBgColor("yellow").text("yellow"); 
                }).wait(1000,function () {       
                    div.changeBgColor("blue").text("blue");      
                });
            });
        });
        <!DOCTYPE html>
        <html>
        <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
        </head>
        <body>
        <p><button id="start">Start</button>&nbsp;<span></span></p>
        
        <div style="display:inline-block;background:blue;height:100px;width:100px;"></div>
        <div style="display:inline-block;background:blue;height:100px;width:100px;"></div>
        </body>
        </html>

        queue() 方法允许你创建一个函数队列 在选定的元素上执行。 dequeue() 方法执行它们 顺序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-07-26
          • 2011-07-20
          • 1970-01-01
          • 2011-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多