jQuery:等待/延迟1秒钟而不执行代码

175

我无法让jQuery中的.delay方法起作用:

$.delay(3000); // not working
$(queue).delay(3000); // not working
我正在使用一个while循环来等待一个不受控制的变化值大于或等于另一个值,但我找不到任何方法来暂停执行X秒钟。

尝试在回调函数中使用setTimeout。 - theshadowmonkey
你正在使用哪个版本的jQuery? - L7ColWinters
1
这不是delay函数设计的目的,它是为排队的jQuery事件(如fade().delay().show())之间使用的。你需要setTimeOut函数。 - JoJa
@JoJa:你的主要观点是正确的,然而show(和hide)的无参数形式不使用效果队列。 - Jay Tomten
3
请说明您想通过延迟实现什么目的。所有JavaScript代码都在单个线程上执行,冻结它X秒可能会影响用户体验。 - Dmitry Shkuropatsky
10个回答

279
您也可以通过这种方式延迟某些操作:
setTimeout(function (){
  
  // Something you want delayed.
            
}, 5000); // How long you want the delay to be, measured in milliseconds.

10
提供一个提示,这不会中断程序的执行流程,因此如果您需要暂停所有操作几秒钟,您将需要像Niessner发布的那样使用一些东西。 - Joshua Pinter
是的...它是对函数的回调,不会阻塞。感谢您的答案,它解决了我的问题。 - Bertus Kruger
如果频率非常短,而我们又预计此函数将永远运行,那么它最终会导致堆栈溢出吗? - Suicide Bunny

205

$.delay被用来延迟动画队列中的动画,而不是停止执行。

你需要递归调用一个使用setTimeout每秒钟执行一次检查的方法,而不是使用while循环:

var check = function(){
    if(condition){
        // run when condition is met
    }
    else {
        setTimeout(check, 1000); // check again in a second
    }
}

check();

2
我认为,setTimeout就足够了。 - Jiemurat
3
你太棒了,兄弟!这正是我需要修复我的代码的东西。 - jemiloii
@Jiemurat 和未来的任何人:setTimeout 不会中断执行流程。Niessner 的伟大代码在条件成立之前一直保持这种状态! - Gabrer
如果您不需要打破执行流程,可以简单地使用 setTimeout() - Joshua Pinter
我总是得到“check不是一个函数”的错误,但我的check函数有两个参数。 - Black
如果你想让你的代码在条件满足时立即生效,可以使用setTimeout(check,0); - reverie_ss

39

ES6 setTimeout

setTimeout(() => {
  console.log("we waited 204586560000 ms to run this code, oh boy wowwoowee!");
}, 204586560000);

编辑:204586560000毫秒是原问题和本回答之间的大致时间...假设我计算正确。


8
非常好,使用原始问题中的大约时间来回答。 - Fuzzybear

24
如果你正在使用ES6特性并且在一个异步函数中,你可以使用这个函数有效地暂停代码执行一段时间:
const delay = millis => new Promise((resolve, reject) => {
  setTimeout(_ => resolve(), millis)
});

使用方法如下:

await delay(5000);

如果您在异步函数中,它会停顿请求的毫秒数,但仅在此情况下。以下是示例:

const myFunction = async function() {
  // first code block ...

  await delay(5000);

  // some more code, executed 5 seconds after the first code block finishes
}

1
我在异步函数中以类似的方式解决了这个问题,只需执行以下操作: await setTimeout(_ => {}, millis); 然后移到下一行。 - Chantelle Chan
2
等待一个新的 Promise,在 1000 毫秒后解析它。 - Splash

10

jQuery 的 delay 函数是用于动画效果和队列的,参见delay文档和其中的示例:

$('#foo').slideUp(300).delay(800).fadeIn(400);

如果你想观察一个变量的变化,你可以做如下操作:

(function() {
    var observerInterval = setInterval(function() {
        if (/* check for changes here */) {
           clearInterval(observerInterval);
           // do something here
        }
    }, 1000);
})();

setInterval有第二个必填参数,即毫秒时间;) - narcolepticvolcano
1
谢谢@sara.potyscki,已修复。 - Julian D.
@JulianD。感谢您的建议。我在搜索解决方案时遇到了这个问题。这正是我项目所需要的。 - Cheryl Velez

9

JavaScript setTimeout 是一个非常好的解决方案:

function funcx()
   {
   // your code here
   // break out here if needed
   setTimeout(funcx, 3000);
   }

funcx();

delay函数在jQuery中主要用于延迟jQuery动画队列中的动画。


7

delay()不能停止代码流然后重新运行它。在JavaScript中,没有实际的方法可以做到这一点,所有的操作都必须通过带回调参数的函数来完成,例如大家提到的setTimeout

jQuery的delay()的目的是使动画队列在执行之前等待一段时间。因此,例如$(element).delay(3000).fadeIn(250);将使元素在3秒后淡入。


5

Javascript是一种异步编程语言,所以你不能暂停执行代码;唯一能[伪]暂停执行的方式是使用setTimeout(),它不是延迟而是“延迟函数回调”。


如果您对setTimeout()的这种“睡眠”用法感兴趣,您可能想查看此线程https://dev59.com/jnNA5IYBdhLWcg3wdtpd#39914235 - Tms91

5
    function sleep(num) {
        let now = new Date();
        let stop = now.getTime() + num;
        while(true) {
            now = new Date();
            if(now.getTime() > stop) return;
        }
    }

    sleep(1000);   // 1 second 
    alert('here');

该函数获取当前时间的毫秒数,加上num(即未来时间),其中num是以毫秒为单位加到当前时间的。

无限循环开始检查当前时间,直到当前时间晚于前面所指定的时间,一旦发生这种情况,该函数停止运行并继续执行此函数调用后的任何内容。


请提供一些关于答案的信息,以便未来的读者从您的答案中获得更多信息。 - Not A Bot
2
这种方法会极大地占用CPU,这样的睡眠可能会导致网页冻结,用户不会喜欢。不要使用它。 - walv

4

只使用Javascript可以在没有jQuery的情况下工作

<!DOCTYPE html>
<html>
    <head>
        <script>
            function sleep(miliseconds) {
                var currentTime = new Date().getTime();
                while (currentTime + miliseconds >= new Date().getTime()) {
                }
            }

            function hello() {
                sleep(5000);
                alert('Hello');
            }
            function hi() {
                sleep(10000);
                alert('Hi');
            }
        </script>
    </head>
    <body>
        <a href="#" onclick="hello();">Say me hello after 5 seconds </a>
        <br>
        <a href="#" onclick="hi();">Say me hi after 10 seconds </a>


    </body>
</html>

2
在JavaScript中循环等待是个坏主意! 当循环正在运行时,所有JavaScript功能都将停止。这将会产生意想不到的副作用。最好使用非阻塞函数,例如setTimeout()。 - Kevin G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接