JavaScript中类似于Java的Thread.sleep()方法的等价方法是什么?

219

在JavaScript中,与Java的Thread.sleep()相当的方法是什么?

9个回答

241
简单的回答是没有这样的函数。
你最接近的东西是:
var millisecondsToWait = 500;
setTimeout(function() {
    // Whatever you want to do after the wait
}, millisecondsToWait);

请注意,你特别不想进行繁忙等待(例如在自旋循环中),因为你的浏览器几乎肯定是在单线程环境中执行你的JavaScript。

以下是一些其他关于JavaScript线程的SO问题:

而这个问题也可能会有所帮助:


1
请查看JavaScript中的setTimeout()和setInterval()函数。 - Mahesh Velaga
9
为了促进良好的编码实践,最好在代码示例中在 "500" 后插入一个分号,并初始化 "millisecondsToWait" (例如,通过在其前面加上 "var")。这样,如果有人复制并粘贴示例,他们不会得到一个暗示的全局变量。 - Steve Harrison
2
很好的发现,Steve。我已经编辑了我的答案以反映你的评论。 - Daniel Pryden
ES6将会有一个新的操作符yield,可以用来“模拟”线程。请参考http://taskjs.org/获取示例库。 - snorbi
使用“setTimeout”不会停止JavaScript线程并等待。只有在调用堆栈为空时,计数才开始。但这取决于您的意图,您想使用哪种方法。 - deftextra

93

尝试使用这段代码。我希望它对你有用。

function sleep(seconds) 
{
  var e = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= e) {}
}

6
完全做到了它应该做的。 - maazza
111
这不会使线程进入休眠状态,只会让线程进行浪费计算,可能会阻塞用户界面。不建议这样做。 - superdweebie
21
那是一种“忙等待”,也就是你在“烧掉线程”。 - Csaba Toth
22
对于我的单元测试目的来说,这很有用。当然,不适用于生产环境。 - armandomiani
4
这个想法很糟糕。 - Alexis Dufrenoy
显示剩余11条评论

80

假设您能够使用 ECMAScript 2017,则可以通过使用 async/await 和 setTimeout 来模拟类似的行为。下面是一个 sleep 函数示例:

async function sleep(msec) {
    return new Promise(resolve => setTimeout(resolve, msec));
}

然后,您可以在任何其他异步函数中像这样使用sleep函数:

async function testSleep() {
    console.log("Waiting for 1 second...");
    await sleep(1000);
    console.log("Waiting done."); // Called 1 second after the first console.log
}

这种方式非常好,因为它避免了需要回调函数的情况。不过缺点是只能在异步函数中使用。在幕后,testSleep函数被暂停,等待睡眠完成后恢复执行。

根据MDN文档:

等待表达式会导致异步函数的执行暂停,直到Promise被兑现或拒绝,并在兑现后恢复异步函数的执行。

详细说明请参见:


1
这是2017年推荐的方法。 - david.barkhuizen
5
2020年也是如此 :) - Aditya Anand

10

为了得到最佳解决方案,请使用ECMAScript 2017的async/await语句

只有在async函数内部才能使用await

function sleep(time) {
    return new Promise((resolve) => {
        setTimeout(resolve, time || 1000);
    });
}

await sleep(10000); //this method wait for 10 sec.

注意:async/await 实际上并不像 Thread.sleep 那样停止线程,而是模拟它


1
抄袭他人答案是不好的。 - Shereef Marzouk

8

没有直接的等待功能,因为它会暂停网页。但是有一个setTimeout()函数,例如:

function doSomething() {
  thing = thing + 1;
  setTimeout(doSomething, 500);
}

闭包示例(感谢Daniel):
function doSomething(val) {
  thing = thing + 1;
  setTimeout(function() { doSomething(val) }, 500);
}

第二个参数是触发前的毫秒数,您可以将其用于时间事件或在执行操作之前等待。

编辑:根据评论更新,以便获得更清晰的结果。

5

您可以编写一个旋转循环(只是循环执行某种计算以延迟函数的循环),或者使用:

setTimeout("Func1()", 3000);

3秒后将调用'Func1()'。

编辑:

感谢评论者,但您可以将匿名函数传递给setTimeout。

setTimeout(function() {
   //Do some stuff here
}, 3000);

这种方法更加高效,而且不需要调用JavaScript的eval函数。


我希望当前线程等待指定秒数的时间。 - Niger
循环运行导致CPU利用率高。 - Niger
15
永远不要引用 setTimeout 的第一个参数 —— 传递匿名函数或函数引用。修正后的版本是:setTimeout(Func1, 3000)。 - Steve Harrison
4
引用setTimeout的第一个参数会不必要地触发"eval()"。 - Steve Harrison
2
@Nick:不,如果你想传递参数,你需要使用闭包。 - Daniel Pryden
显示剩余2条评论

4

setTimeout不会在您自己的线程上暂停和恢复,但Thread.sleep会。在Javascript中没有实际的等价物。


0
或者你可以使用setInterval函数,在指定的毫秒数后调用特定的函数。只需在Google上搜索setInterval原型即可。我不太记得了。

-1
这最终对我有所帮助:
    var x = 0;
    var buttonText = 'LOADING';

    $('#startbutton').click(function(){
        $(this).text(buttonText);
        window.setTimeout(addDotToButton,2000);
    })

    function addDotToButton(){
        x++;
        buttonText += '.';
        $('#startbutton').text(buttonText);

        if (x < 4) window.setTimeout(addDotToButton, 2000);
        else location.reload(true);
    }

5
setTimeout早在很久以前就已经提到了。剩下的代码与问题无关。 - AbcAeffchen

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