什么是sleep()的JavaScript版本?

时间:2009-06-04 14:41:10

标签: javascript sleep

是否有更好的方法来设计JavaScript sleep而不是以下pausecomp函数(taken from here)?

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

这不是Sleep in JavaScript - delay between actions的副本;我希望在函数中间有一个真正的睡眠,而不是在一段代码执行之前的延迟。

87 个答案:

答案 0 :(得分:1703)

2017 - 2019年更新

自2009年提出此问题以来,JavaScript已经发生了重大变化。所有其他答案现在已经过时或过于复杂。这是目前的最佳做法:

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

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two seconds later, showing sleep in a loop...');

  // Sleep in loop
  for (let i = 0; i < 5; i++) {
    if (i === 3)
      await sleep(2000);
    console.log(i);
  }
}

demo();

就是这样。 await sleep(<duration>)

请注意,

  1. await只能在前缀为async关键字的函数中执行,或者在某些环境中(例如Chrome DevTools控制台或Runkit)在脚本的top level执行。< / LI>
  2. await仅暂停当前的async功能
  3. 两个新的JavaScript功能帮助编写了这个“睡眠”功能:

    兼容性

    如果出于某种奇怪的原因,您使用的是早于7的节点(已达到end of life),或者定位到旧版浏览器,async / await仍然可以通过{ {3}}(使用Babel插件将transpile JavaScript +新功能转换为普通旧JavaScript的工具。

答案 1 :(得分:841)

(参见updated answer for 2016

我认为想要执行某个操作,等待,然后执行其他操作是完全合理的。如果您习惯于使用多线程语言编写,那么您可能会想要在一段时间内执行执行,直到线程被唤醒。

这里的问题是JavaScript是一个基于事件的单线程模型。虽然在特定情况下,让整个引擎等待几秒钟可能会很好,但总的来说这是不好的做法。假设我想在编写自己的函数时使用你的函数?当我打电话给你的方法时,我的方法都会冻结。如果JavaScript可以某种方式保留你的函数的执行上下文,将它存储在某处,然后将其恢复并稍后继续,然后就可以进行睡眠,但这基本上就是线程化。

所以你几乎坚持别人的建议 - 你需要将你的代码分解成多个功能。

那么你的问题是一个错误的选择。没有办法以你想要的方式睡觉,你也不应该寻求你建议的解决方案。

答案 2 :(得分:621)

在JavaScript中,我重写了每个函数,以便它可以尽快结束。您希望浏览器重新进入控制状态,以便进行DOM更改。

每次我想在我的功能中间睡觉时,我都会重构使用setTimeout()

  

我要编辑这个答案,因为我认为这很有用:

任何语言中臭名昭着的睡眠或延迟功能都备受争议。有些人会说应该总是有一个信号或回调来激发给定的功能,其他人会争辩说有时候任意延迟的时刻都是有用的。我说每个人都有自己的规则,而且这个规则永远都不能规定这个行业。

编写一个睡眠函数很简单,使用JavaScript Promises更加实用:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});

答案 3 :(得分:284)

仅适用于debug / dev ,如果对某人有用,我会发布此内容

有趣的东西,在Firebug(以及可能还有其他js游戏机)中,只有在指定睡眠时间后才会进入,只有在指定睡眠时间后才会发生(...)

function sleepFor( sleepDuration ){
    var now = new Date().getTime();
    while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

使用示例:

function sleepThenAct(){ sleepFor(2000); console.log("hello js sleep !"); }

答案 4 :(得分:171)

我同意其他海报,忙碌的睡眠只是一个坏主意。

但是,setTimeout不会阻止执行,它会在超时设置后立即执行函数的下一行,而不会在超时到期后执行,这样就无法完成睡眠完成的相同任务。

这样做的方法是将您的功能分解为部件之前和之后。

function doStuff()
{
  //do some things
  setTimeout(continueExecution, 10000) //wait ten seconds before continuing
}

function continueExecution()
{
   //finish doing things after the pause
}

确保您的函数名称仍能准确描述每个部分的作用(I.E. GatherInputThenWait和CheckInput,而不是funcPart1和funcPart2)

修改

此方法的目的是在您超时之后不执行您决定的代码行,同时仍然将控制权返回给客户端PC以执行其排队的任何其他内容。

进一步修改

正如评论中指出的那样,这绝对不会在循环中起作用。你可以做一些花哨的(丑陋的)黑客攻击让它在一个循环中工作,但总的来说这只会造成灾难性的意大利面条代码。

答案 5 :(得分:119)

对于DEITY的爱,请不要做一个忙碌的等待睡眠功能。 setTimeoutsetInterval可以为您提供所需的一切。

答案 6 :(得分:112)

我知道这是一个古老的问题,但如果(像我一样)你使用的是带有Rhino的Javascript,你可以使用......

try
{
  java.lang.Thread.sleep(timeInMilliseconds);
}
catch (e)
{
  /*
   * This will happen if the sleep is woken up - you might want to check
   * if enough time has passed and sleep again if not - depending on how
   * important the sleep time is to you.
   */
}

答案 7 :(得分:66)

如果您正在使用jQuery,有人实际上创建了一个“延迟”插件,它只不过是setTimeout的包装器:

// Delay Plugin for jQuery
// - http://www.evanbot.com
// - © 2008 Evan Byrne

jQuery.fn.delay = function(time,func){
    this.each(function(){
        setTimeout(func,time);
    });

    return this;
};

然后您可以按预期在一行函数调用中使用它:

$('#warning')
.addClass('highlight')
.delay(1000)
.removeClass('highlight');

答案 8 :(得分:43)

我也搜索过睡眠解决方案(不适用于生产代码,仅适用于开发/测试)并找到了这篇文章:

http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html

...这里是客户端解决方案的另一个链接:http://www.devcheater.com/

此外,当您呼叫alert()时,您的代码也会暂停,同时显示警报 - 需要找到一种不显示警报但获得相同效果的方法。 :)

答案 9 :(得分:30)

你走了。正如代码所说,不要成为一个糟糕的开发者并在网站上使用它。这是一个开发实用功能。

// Basic sleep function based on ms.
// DO NOT USE ON PUBLIC FACING WEBSITES.
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}

答案 10 :(得分:26)

这是使用同步XMLHttpRequest的简单解决方案:

function sleep(n){
  var request = new XMLHttpRequest();
  request.open('GET', '/sleep.php?n=' + n, false);  // `false` makes the request synchronous
  request.send(null);
}

sleep.php的内容:

<?php sleep($_GET['n']);

现在调用它: 睡眠(5);

答案 11 :(得分:18)

我个人喜欢简单:

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

然后:

sleep(2); // Sleeps for 2 seconds

我在P5js中创建脚本时一直使用它来创建假加载时间

答案 12 :(得分:18)

首先:

定义一个你想要执行的函数:

function alertWorld(){
  alert("Hello World");
}

然后使用setTimeout方法安排执行:

setTimeout(alertWorld,1000)

注意两件事

  • 第二个参数是以毫秒为单位的时间
  • 作为第一个参数,你必须只传递函数的名称(引用),而没有括号

答案 13 :(得分:15)

使事情看起来像大多数人想要的更好的解决方案是使用匿名函数:

alert('start');
var a = 'foo';
//lots of code
setTimeout(function(){  //Beginning of code that should run AFTER the timeout
    alert(a);
    //lots more code
},5000);  // put the timeout here

这可能是你最接近你能做到的事情。

注意,如果您需要多次睡眠,这可能会让您感到尴尬,实际上您可能需要重新考虑您的设计。

答案 14 :(得分:10)

我会将setTimeOut封装在Promise中,以便与其他异步任务保持代码一致性:Fiddle中的演示

function sleep(ms)
{
    return(new Promise(function(resolve, reject) {        
        setTimeout(function() { resolve(); }, ms);        
    }));    
}

像这样使用:

sleep(2000).then(function() { 
   // Do something
});

如果您曾经使用过Promises,那么很容易记住语法。

答案 15 :(得分:9)

这里的大多数答案都是误导或至少过时的。没有理由javascript必须是单线程的,事实上它不是。今天所有主流浏览器都支持工作者,在此之前,其他javascript运行时如Rhino和Node.js支持多线程。

&#39; Javascript是单线程的&#39;不是一个有效的答案。例如,在worker中运行sleep函数不会阻止在ui线程中运行的任何代码。

在支持生成器和yield的较新运行时,可以在单线程环境中为sleep函数带来类似的功能:

// This is based on the latest ES6 drafts.
// js 1.7+ (SpiderMonkey/Firefox 2+) syntax is slightly different

// run code you want to sleep here (ommit star if using js 1.7)
function* main(){
    for (var i = 0; i < 10; i++) {
        // to sleep for 10 milliseconds 10 times in a row
        yield 10;
    }

    yield 5;
    console.log('I just slept 5 milliseconds!');
}

// resume the given generator after ms milliseconds
function resume(ms, generator){
    setTimeout(function(){
        // ommit .value if using js 1.7
        var nextSleep = generator.next().value;
        resume(nextSleep, generator);
    }, ms);
}

// initialize generator and get first sleep for recursive function
var
    generator = main(),
    firstSleep = generator.next().value;

// initialize recursive resume function
resume(firstSleep, generator);

这种模仿睡眠不同于真正的睡眠功能,因为它不会阻塞线程。它只是javascript的当前setTimeout函数之上的糖。此功能类型已在Task.js中实现,现在可以在Firefox中使用。

答案 16 :(得分:9)

对于浏览器,我同意setTimeout和setInterval是可行的方法。

但对于服务器端代码,它可能需要阻塞功能(例如,因此您可以有效地进行线程同步)。

如果你正在使用node.js和meteor,你可能会遇到在光纤中使用setTimeout的限制。这是服务器端睡眠的代码。

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

请参阅:https://github.com/laverdet/node-fibers#sleep

答案 17 :(得分:8)

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

答案 18 :(得分:8)

我已经在javascript sleep / wait上搜索/搜索了不少网页......如果你想让javascript“跑,延迟,跑”,没有答案......大多数人得到的也是“RUN, RUN(无用的东西),RUN“或”RUN,RUN +延迟RUN“....

所以我吃了一些汉堡,想到了::: 这是一个有效的解决方案...但你必须砍掉你的运行代码... ::: 是的,我知道,这只是一个更容易阅读的重构......还是......

// ......................................... //例1:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setInterval
var i = 0;

function run() {
    //pieces of codes to run
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i >2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==5){document.getElementById("id1").innerHTML= "<p>all code segment finished running</p>"; clearInterval(t); } //end interval, stops run
    i++; //segment of code finished running, next...
}

run();
t=setInterval("run()",1000);

</script>
</body>
</html>

// .................................... //例2:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function run() {
    //pieces of codes to run, can use switch statement
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(1000);}
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(2000);}
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(3000);}
    if (i==3){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>";} //stops automatically
    i++;
}

function sleep(dur) {t=setTimeout("run()",dur);} //starts flow control again after dur

run(); //starts
</script>
</body>
</html>

// ................. 示例3:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function flow() {
    run(i);
    i++; //code segment finished running, increment i; can put elsewhere
    sleep(1000);
    if (i==5) {clearTimeout(t);} //stops flow, must be after sleep()
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow
</script>
</body>
</html>

// .............. 范例4:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout, switch
var i = 0;

function flow() {
    switch(i)
    {
        case 0:
            run(i);
            sleep(1000);
            break;
        case 1:
            run(i);
            sleep(2000);
            break;
        case 5:
            run(i);
            clearTimeout(t); //stops flow
            break;
        default:
            run(i);
            sleep(3000);
            break;
    }
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    i++; //current segment of code finished running, next...
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow control for first time...
</script>
</body>
</html>

答案 19 :(得分:6)

很多答案没有(直接)回答这个问题,而且这个问题也没有......

这是我的两分钱(或函数):

如果你想要比setTimeoutsetInterval更少的笨重的函数,你可以将它们包装在只是颠倒参数顺序的函数中,并给它们提供好名字:

function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }

CoffeeScript版本:

after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms

然后,您可以很好地使用它们与匿名函数:

after(1000, function(){
    console.log("it's been a second");
    after(1000, function(){
        console.log("it's been another second");
    });
});

现在它很容易读作“经过N毫秒,......”(或“每N毫秒......”)

答案 20 :(得分:6)

如果你必须处理同步执行,我可以理解睡眠功能的目的。 setInterval和setTimeout函数创建一个并行执行线程,该线程将执行序列返回给主程序,如果你必须等待给定的结果,这将无效。当然,可以使用事件和处理程序,但在某些情况下不是预期的。

答案 21 :(得分:6)

您可能需要sleep()函数而不是使用setTimeout()的一种情况是,如果您有一个响应用户点击的函数,最终会打开一个新的ie弹出窗口并启动了一些需要的处理在显示弹出窗口之前完成的短时间。将打开的窗口移动到闭包中意味着它通常会被浏览器阻止。

答案 22 :(得分:6)

添加我的两位。我需要忙着等待测试。我不想分割代码,因为那将是很多工作,所以这对我来说很简单。

for (var i=0;i<1000000;i++){                    
     //waiting
  }

我没有看到这样做的任何缺点,它为我做了诀窍。

答案 23 :(得分:6)

可以使用Java的sleep方法完成。我已经在FF和IE中测试了它,它不会锁定计算机,咀嚼资源或导致无休止的服务器命中。对我来说似乎是一个干净的解决方案。

首先,您必须在页面上加载Java并使其方法可用。为此,我这样做了:

<html>
<head>

<script type="text/javascript">

  function load() {
    var appletRef = document.getElementById("app");
    window.java = appletRef.Packages.java;
  } // endfunction

</script>

<body onLoad="load()">

<embed id="app" code="java.applet.Applet" type="application/x-java-applet" MAYSCRIPT="true" width="0" height="0" />

然后,当你想要在JS中无痛停顿时,你所要做的就是:

java.lang.Thread.sleep(xxx)

其中xxx是以毫秒为单位的时间。在我的情况下(通过证明),这是一个非常小的公司的后端订单履行的一部分,我需要打印一个必须从服务器加载的发票。我是通过将发票(作为网页)加载到iFrame然后打印iFrame来完成的。当然,我必须等到页面完全加载才能打印,所以JS必须暂停。我通过让发票页面(在iFrame中)使用onLoad事件更改父页面上的隐藏表单字段来实现此目的。并且打印发票的父页面上的代码看起来像这样(为了清晰起见,不相关的部分切割):

var isReady = eval('document.batchForm.ready');
isReady.value=0;

frames['rpc_frame'].location.href=url;

while (isReady.value==0) {
  java.lang.Thread.sleep(250);
} // endwhile

window.frames['rpc_frame'].focus();
window.frames['rpc_frame'].print();

因此,用户按下按钮,脚本加载发票页面,然后等待,每隔四分之一秒检查发票页面是否完成加载,然后弹出打印对话框,供用户将其发送到打印机。 QED。

答案 24 :(得分:5)

你不能像在JavaScript中那样睡觉,或者你不应该这样。运行sleep或while循环将导致用户的浏览器挂起,直到循环完成。

使用您引用的链接中指定的计时器。

答案 25 :(得分:5)

如果你在node.js上,你可以查看fibers - 节点的本地C扩展,一种多线程模拟。

它允许您以阻止光纤执行的方式执行实际sleep,但它在主线程和其他光纤中无阻塞。

这是一个来自他们自述的新例子:

// sleep.js

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

- 结果是:

$ node sleep.js
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)

答案 26 :(得分:5)

2009年的一个老问题。现在在2015年,ECMAscript 2015又名ES6中定义的发电机可以实现新的解决方案。它在六月份获得批准,但之前在Firefox和Chrome中实现过。现在,睡眠功能可以非繁忙,非阻塞并嵌套在循环和子功能中,而不会冻结浏览器。只需要纯JavaScript,没有库或框架。

以下程序显示了如何制作sleep()runSleepyTask()sleep()函数只是yield语句。它非常简单,实际上更容易直接编写yield语句而不是调用sleep(),但之后就没有睡眠字:-) yield会向{返回一个时间值{1}}内的{1}}方法并等待。实际的&#34;睡眠&#34;使用优质旧next()wakeup()中完成。在回调时,wakeup()方法会触发setTimeout()语句继续,以及&#34;魔法&#34; yield是所有局部变量和它周围的整个调用堆栈仍然完好无损。

使用sleep()或yield的函数必须定义为生成器。通过在关键字next()中添加星号来轻松完成。执行生成器有点棘手。当使用关键字yield调用时,生成器返回一个具有function*方法的对象,但不执行生成器的主体(关键字new是可选的,没有区别)。 next()方法触发生成器主体的执行,直到遇到new为止。包装函数next()启动乒乓:yield等待runSleepyTask()next()等待yield

调用生成器的另一种方法是使用关键字yield,这里它的工作方式类似于简单的函数调用,但它还包括回退到next()的能力。

示例yield*都证明了这一点。它在旋转的3D场景上绘制了一棵树叶。树木被绘制为树干,顶部有3个不同方向的树。然后通过在短暂睡眠后递归调用next()将每个部分绘制为另一个但更小的树。一棵非常小的树被画成一片叶子。

每个叶子在以drawTree()开头的单独任务中有自己的生命。它在drawTree()出生,成长,坐下,褪色,跌倒和死亡。速度由runSleepyTask()控制。这表明了如何轻松完成多任务处理。

&#13;
&#13;
growLeaf()
&#13;
sleep()
&#13;
&#13;
&#13;

3D内容隐藏在setup3D()中,仅包含它以使其比console.log()更无聊。顺便说一句,天使用弧度来衡量。

经测试可在Firefox和Chrome中使用。未在Internet Explore和iOS(iPad)中实现。尝试自己运行它。

在我发现的答案又一次传递之后,Gabriel Ratener在一年前提出了类似的答案:https://stackoverflow.com/a/24401317/5032384

答案 27 :(得分:5)

对于想要通过循环执行一组调用的特定情况,您可以使用类似下面的代码和原型。如果没有原型,可以使用setTimeout替换延迟函数。

function itemHandler(item)
{
    alert(item);
}

var itemSet = ['a','b','c'];

// Each call to itemHandler will execute
// 1 second apart
for(var i=0; i<itemSet.length; i++)
{
    var secondsUntilExecution = i;
    itemHandler.delay(secondsUntilExecution, item)
}

答案 28 :(得分:4)

可以做这样的事情。所有函数都可以继承的睡眠方法:

Function.prototype.sleep = function(delay, ...args) {
    setTimeout(() => this(...args), delay)
}

console.log.sleep(2000, 'Hello world!')

答案 29 :(得分:4)

没有任何依赖关系的最短解决方案:

await new Promise(resolve => setTimeout(resolve, 5000));

答案 30 :(得分:4)

自节点7.6 起,您可以将utils模块中的promisify函数与setTimeout结合使用。

const sleep = require('util').promisify(setTimeout)

常规用法

async function main() {
    console.time("Slept for")
    await sleep(3000)
    console.timeEnd("Slept for")
}

main()

问题用法

async function asyncGenerator() {
    while (goOn) {
      var fileList = await listFiles(nextPageToken);
      await sleep(3000)
      var parents = await requestParents(fileList);
    }
  }

答案 31 :(得分:4)

从此link获取的代码不会冻结comp。但它仅适用于ff。

/**
 * Netscape compatible WaitForDelay function.
 * You can use it as an alternative to Thread.Sleep() in any major programming language
 * that support it while JavaScript it self doesn't have any built-in function to do such a thing.
 * parameters:
 * (Number) delay in millisecond
 */
function nsWaitForDelay(delay) {
    /**
     * Just uncomment this code if you're building an extention for Firefox.
     * Since FF3, we'll have to ask for user permission to execute XPCOM objects.
     */
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

    // Get the current thread.
    var thread = Components.classes["@mozilla.org/thread-manager;1"].getService(Components.interfaces.nsIThreadManager).currentThread;

    // Create an inner property to be used later as a notifier.
    this.delayed = true;

    /* Call JavaScript setTimeout function
      * to execute this.delayed = false
      * after it finish.
      */
    setTimeout("this.delayed = false;", delay);

    /**
     * Keep looping until this.delayed = false
     */
    while (this.delayed) {
        /**
         * This code will not freeze your browser as it's documented in here:
         * https://developer.mozilla.org/en/Code_snippets/Threads#Waiting_for_a_background_task_to_complete
         */
        thread.processNextEvent(true);
    }
}

答案 32 :(得分:4)

首先 - setTimeout和setInterval是应该的用法,因为javascript的回调性质。如果您想使用sleep(),那么控制流或代码的体系结构是不正确的。

话虽如此,我想我仍然可以帮助实现两次睡眠。

  1. 假装同步跑出了我的头顶:

    //a module to do taht //dual-license: MIT or WTF [you can use it anyhow and leave my nickname in a comment if you want to]
    var _=(function(){
     var queue=[];
     var play=function(){
       var go=queue.shift();
         if(go){if(go.a){go.f();play();}else{setTimeout(play,go.t);}}
       }
     return {
       go:function(f){
        queue.push({a:1,f:f});
        },
       sleep:function(t){
        queue.push({a:0,t:t});
        },
       playback:play 
     }
    })();
    

    [也应该可以自动播放]

    //usage
    
    _.go(function(){
    
    //your code
    console.log('first');
    
    });
    
    
    _.sleep(5000);
    
    _.go(function(){
    
    //your code
    console.log('next');
    
    });
    
    //this triggers the simulation
    _.playback();
    
  2. 真正的同步运行

  3. 有一天我给了它很多想法,我在javascript中真正睡眠的唯一想法是技术性的。

    睡眠功能必须是同步 AJAX调用,超时设置为睡眠值。这就是拥有真实sleep()

    的唯一途径

答案 33 :(得分:4)

如果你正确的睡眠功能

var sleep = function(period, decision, callback){
    var interval = setInterval(function(){
        if (decision()) {
            interval = clearInterval(interval);
            callback();
        }
    }, period);
}

你有一个多次调用的异步函数

var xhr = function(url, callback){
    // make ajax request
    // call callback when request fulfills
}

你设置这样的项目:

var ready = false;

function xhr1(){
    xhr(url1, function(){ ready = true;});  
}
function xhr2(){
    xhr(url2, function(){ ready = true; }); 
}
function xhr3(){
    xhr(url3, function(){ ready = true; }); 
}

然后你可以这样做:

xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
    // do more
});

而不是像这样无休止的回调缩进:

xhr(url1, function(){
    xhr2(url2, function(){
        xhr3(url3, function(){
            // do more
        });
    });
});

答案 34 :(得分:3)

从现在起 (node 16+),setTimeout() 的新承诺版本可用:

import { setTimeout } from 'timers/promises'

await setTimeout(5000) 

答案 35 :(得分:3)

如果你真的需要睡觉()来测试一些东西。但请注意,在调试时大多数情况下它会崩溃浏览器 - 这可能就是你无论如何都需要它的原因。在生产模式中,我会注释掉这个功能。

function pauseBrowser(millis) {
    var date = Date.now();
    var curDate = null;
    do {
        curDate = Date.now();
    } while (curDate-date < millis);
}

请勿在循环中使用新的Date(),除非您要浪费内存,处理能力,电池以及设备的使用寿命。

答案 36 :(得分:2)

一个睡眠功能,使用同步调用让操作系统执行此操作。 使用您喜欢的任何OS睡眠命令。从使用CPU时间的角度来看,它并不忙。

我在一个不存在的地址上选择了ping。

const cp = require('child_process');

function sleep(ms)
{ 
    try{cp.execSync('ping 192.0.2.0 -n 1 -w '+ms);}
    catch(err){}
}

验证其有效的测试

console.log(Date.now());
console.log(Date.now());
sleep(10000);
console.log(Date.now());
console.log(Date.now());

以及一些测试结果。

1491575275136
1491575275157

(10秒后)

1491575285075
1491575285076

答案 37 :(得分:2)

await支持和bluebird promise

await bluebird.delay(1000);

这将像c语言的同步sleep(1)一样工作。我最喜欢的解决方案。

答案 38 :(得分:2)

试试这个简单的javascript函数:

function sleep(milliseconds) {
    var $return = false;
    if (typeof importScripts == 'function') {
        var sleep_xhr = function (milliseconds) {
            try {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', 'http://128.0.0.1:' + (Math.random() * 100000).toFixed(0) + '/', false);
                xhr.timeout = milliseconds;
                xhr.send();
            } catch (E) {
                // Nothing to do...
            }
        };
        milliseconds = milliseconds | 0;
        if (milliseconds > 0) {
            var start = Date.now();
            while (Date.now() < start + milliseconds) {
                sleep_xhr((start + milliseconds) - Date.now());
            }
            $return = Date.now() - start;
        }
    }
    return $return;
}

注意:此功能仅适用于网络工作者

答案 39 :(得分:2)

我知道问题是关于睡眠,显然答案是不可能。我认为睡眠的常见需求是按顺序处理异步任务,我知道我必须要处理它。

许多情况下可能能够使用promises(AJAX请求常用)。它们允许您以同步方式执行异步操作。还有成功/失败的处理方式,它们可以被链接。

它们是ECMAScript 6的一部分,所以浏览器支持还没有,主要是IE不支持它们。还有一个名为Q的图书馆,用于做出承诺。

参考文献: http://www.html5rocks.com/en/tutorials/es6/promises/

https://github.com/jakearchibald/es6-promise#readme(Shim for old or IE浏览器)

答案 40 :(得分:2)

  await new Promise(resolve => setTimeout(resolve, 2000));

确保您的调用函数是异步的

已验证并且可以正常工作

答案 41 :(得分:2)

这真的不是一个好主意,做这样的事情会导致整个页面冻结,同时系统等待你的函数返回。

答案 42 :(得分:2)

这将帮你解决问题。

var reloadAfter = 10; //seconds
var intervalId = setTimeout(function() {
    //code you want to execute after the time waiting
}, reloadAfter * 1000); // 60000 = 60 sec = 1 min

答案 43 :(得分:2)

拥抱javascript的异步性质!

以下所有内容都会立即返回,但只有一个地方可以放置您希望在发生某些事情后运行的代码。

我在此概述的方法都针对不同的用例,并且根据其复杂程度进行了大致排序。

不同的事情如下:

  • 等待某些条件成为现实
  • 在调用单个回调之前等待一组方法(以任何顺序)完成
  • 在调用回调之前以特定顺序运行一系列具有共享状态的异步方法

<强>等待

等待查看某些条件是否为真是有用的,因为没有可访问的回调来告诉你何时某些事情已经完成。

这是一个非常基本的实现,假设条件在某些时候会变为真。通过一些调整,它可以扩展为更有用(例如通过设置呼叫限制)。 (我昨天才写这个!)

function waitFor(predicate, successCallback) {
    setTimeout(function () {
        var result = predicate();
        if (result !== undefined)
            successCallback(result);
        else
            waitFor(predicate, successCallback);
    }, 100);
}

调用代码:

    beforeEach(function (done) {
        selectListField('A field');

        waitFor(function () {
            var availableOptions = stores.scrapeStore(optionStore);
            if (availableOptions.length !== 0)
                return availableOptions;
        }, done);
    });

我在这里打电话给你加载一个extjs&#39; store&#39;等待直到商店在继续之前包含一些东西(beforeEach是一个茉莉花测试框架的东西)。

等待几件事情完成

我需要做的另一件事是在完成不同方法的加载后运行一个回调。你可以这样做:

createWaitRunner = function (completionCallback) {
    var callback = completionCallback;
    var completionRecord = [];
    var elements = 0;

    function maybeFinish() {
        var done = completionRecord.every(function (element) {
            return element === true
        });

        if (done)
            callback();
    }

    return {
        getNotifier: function (func) {
            func = func || function (){};

            var index = elements++;
            completionRecord[index] = false;

            return function () {
                func.applyTo(arguments);
                completionRecord[index] = true;
                maybeFinish();
            }
        }
    }
};

调用代码:

    var waiter = createWaitRunner(done);

    filterList.bindStore = waiter.getNotifier();
    includeGrid.reconfigure = waiter.getNotifier(function (store) {
        includeStore = store;
    });
    excludeGrid.reconfigure = waiter.getNotifier(function (store) {
        excludeStore = store;
    });

您要么等待通知,要么还可以包含使用传递给函数的值的其他函数。调用所有方法后,将运行done

按顺序运行异步方法

当我有一系列异步方法连续调用时(我再次在测试中),我使用了不同的方法。这有点类似于你可以在the Async library中得到的东西 - 系列做同样的事情,我先读了一下这个库,先看看它是否符合我的要求。我认为我的测试工作有一个更好的API(+实现很有趣!)。

//provides a context for running asyncronous methods syncronously
//the context just provides a way of sharing bits of state
//use run to execute the methods.  These should be methods that take a callback and optionally the context as arguments
//note the callback is provided first so you have the option of just partially applying your function to the arguments you want
//instead of having to wrap even simple functions in another function

//when adding steps you can supply either just a function or a variable name and a function
//if you supply a variable name then the output of the function (which should be passed into the callback) will be written to the context
createSynchronisedRunner = function (doneFunction) {
    var context = {};

    var currentPosition = 0;
    var steps = [];

    //this is the loop. it is triggered again when each method finishes
    var runNext = function () {
        var step = steps[currentPosition];
        step.func.call(null,
                       function (output) {
                           step.outputHandler(output);
                           currentPosition++;

                           if (currentPosition === steps.length)
                               return;

                           runNext();
                       }, context);
    };

    var api = {};

    api.addStep = function (firstArg, secondArg) {
        var assignOutput;
        var func;

        //overloads
        if (secondArg === undefined) {
            assignOutput = function () {
            };
            func = firstArg;
        }
        else {
            var propertyName = firstArg;
            assignOutput = function (output) {
                context[propertyName] = output;
            };
            func = secondArg;
        }

        steps.push({
                       func: func,
                       outputHandler: assignOutput
                   });
    };

    api.run = function (completedAllCallback) {
        completedAllCallback = completedAllCallback || function(){};

        var lastStep = steps[steps.length - 1];
        var currentHandler = lastStep.outputHandler;
        lastStep.outputHandler = function (output) {
            currentHandler(output);
            completedAllCallback(context);
            doneFunction();
        };

        runNext();
    };

    //this is to support more flexible use where you use a done function in a different scope to initialisation
    //eg the done of a test but create in a beforeEach
    api.setDoneCallback = function (done) {
        doneFunction = done;
    };

    return api;
};

调用代码:

beforeAll(function (done) {
    var runner = createSynchronisedRunner(done);
    runner.addStep('attachmentInformation', testEventService.getAttachmentCalled.partiallyApplyTo('cat eating lots of memory.jpg'));
    runner.addStep('attachment', getAttachment.partiallyApplyTo("cat eating lots of memory.jpg"));
    runner.addStep('noAttachment', getAttachment.partiallyApplyTo("somethingElse.jpg"));
    runner.run(function (context) {
        attachment = context.attachment;
        noAttachment = context.noAttachment;
    });
});

PartiallyApplyTo这里基本上是Doug Crockford对Curry实施的重命名版本。我正在使用的许多东西都将回调作为最终参数,因此可以像这样进行简单的调用,而不必使用额外的函数来包装所有内容。

希望那里的一些想法对人们有用。

答案 44 :(得分:2)

如果你想建议不要失去表现。 setTimeout是您预期的sleep。 但是,如果你想要一个代码被sleep“划分为中间”的语法,我们可以这样做:

sleep=function(tm,fn){
   window.setTimeout(fn,tm);
}

然后,perpare的功能如下:

var fnBeforeSleep=function(){

 //All codes before sleep

}  

var fnAfterSleep=function(){

 //All codes after sleep

}  

然后:

fnBeforeSleep();
sleep(2000,
fnAfterSleep);

YEP!语法上,它非常接近:

fnBeforeSleep();
sleep(2000); 
fnAfterSleep();

答案 45 :(得分:1)

这里大多数解决方案的问题是他们倒回堆栈。在某些情况下,这可能是一个大问题。在此示例中,我将展示如何以不同方式使用迭代器来模拟 实际睡眠

在这个例子中,生成器正在调用它自己的next(),所以一旦它发生,它就是它自己的。

var h=a();
h.next().value.r=h; //that's how U run it, best I came up with

//sleep without breaking stack !!!
function *a(){
    var obj= {};

    console.log("going to sleep....2s")

    setTimeout(function(){obj.r.next();},2000)  
     yield obj;

    console.log("woke up");
    console.log("going to sleep no 2....2s")
    setTimeout(function(){obj.r.next();},2000)  
     yield obj;

     console.log("woke up");
    console.log("going to sleep no 3....2s")

     setTimeout(function(){obj.r.next();},2000) 
     yield obj;

    console.log("done");

}

答案 46 :(得分:1)

如果你想睡一个你创建为处理程序的匿名函数,我建议如下:

function()
{
if (!wait_condition)
    {
    setTimeout(arguments.callee, 100, /*comma-separated arguments here*/);
    }
//rest of function
}

此代码显示“如果尚未满足等待条件,请使用这些参数再次调用此函数。”我已经使用这个方法将相同的参数传递给我的处理程序,有效地使这段代码成为非轮询sleep()(只能在你的函数开始时使用)。

答案 47 :(得分:1)

如果您确实希望完全阻塞主线程并防止事件循环从事件队列中拉出,那么这是一种不错的方法,而无需创建任何函数,新的Date对象或泄漏任何变量。我知道这个愚蠢的问题已经有上百万个答案,但是我没有看到有人使用这个确切的解决方案。这仅是现代浏览器。

警告:这不是您要投入生产的东西,它仅对了解浏览器事件循环很有帮助。它可能甚至对任何测试都没有用。它不像普通的系统睡眠功能,因为javascript运行时仍在每个周期工作。

for (let e = performance.now() + 2000; performance.now() < e; ) {}

在这里使用的setTimeout回调直到至少2秒后才会被调用,即使它几乎立即进入事件队列:

setTimeout(function() {
  console.log("timeout finished");
}, 0);

for (let e = performance.now() + 2000; performance.now() < e; ) {}
console.log("haha wait for me first");

您将遇到〜2秒的暂停,然后再看

haha wait for me first
timeout finished

相对于Date.now(),使用performance.now()的好处在于Date对象是

受时钟偏斜和系统时钟调整的影响。的 时间的价值可能并不总是单调增加的, 后续值可能会减少或保持不变。 *

一般来说,now()更适合于高精度地测量时间差异。

使用for循环的好处是,您可以在运行之前将变量设置为本地变量。这样一来,您就可以在循环外进行“加法运算”,同时仍然保持“单线”状态。希望这可以最大程度地减少这种热循环刻录的CPU负载。

答案 48 :(得分:1)

您可以使用具有递增较大值的闭包调用setTimeout()。

var items = ['item1', 'item2', 'item3'];

function functionToExecute(item) {
  console.log('function executed for item: ' + item);
}

$.each(items, function (index, item) {
  var timeoutValue = index * 2000;
  setTimeout(function() {
    console.log('waited ' + timeoutValue + ' milliseconds');
    functionToExecute(item);
  }, timeoutValue);
});

结果:

waited 0 milliseconds
function executed for item: item1
waited 2000 milliseconds
function executed for item: item2
waited 4000 milliseconds
function executed for item: item3 

答案 49 :(得分:1)

使用打字稿吗?

这是一个可以等待的快速sleep()实现。这与最高答案尽可能相似。除了在打字稿上将ms键入为number以外,它在功能上是等效的。

const sleep = (ms: number) =>
  new Promise((resolve) => setTimeout(resolve, ms));

async function demo() {
  console.log('Taking a break for 2s (2000ms)...');
  await sleep(2000);
  console.log('Two seconds later');
}

demo();

就这样。 await sleep(<duration>)

请注意

  1. await仅可在带有前缀async的函数中执行,或在某些环境中(例如Chrome DevTools控制台或Runkit)在脚本的top level中执行。 / li>
  2. await仅暂停当前的async函数

答案 50 :(得分:1)

我在解决方案中导航了一天,但仍在考虑如何在使用回调时保持可链接性。每个人都熟悉以同步方式逐行运行代码的传统编程风格。 SetTimeout使用回调,因此下一行不会等待它完成。这让我想到如何使它同步,以便做出一个“睡眠”#34;功能

从一个简单的协程开始:

function coroutine() {
    console.log('coroutine-1:start');
    sleepFor(3000); //sleep for 3 seconds here
    console.log('coroutine-2:complete');
}

我想在中间睡3秒但不想控制整个流程,所以协程必须由另一个线程执行。我考虑Unity YieldInstruction,并在下面修改协程:

function coroutine1() {
    this.a = 100;
    console.log('coroutine1-1:start');
    return sleepFor(3000).yield; // sleep for 3 seconds here
    console.log('coroutine1-2:complete');
    this.a++;
}

var c1 = new coroutine1();

声明sleepFor原型:

sleepFor = function(ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?sleepFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    setTimeout(function() {
        new Function(funcArgs, funcBody).apply(context, args);
    }, ms);
    return this;
}

运行coroutine1(我在IE11和Chrome49中测试过)后,你会看到它在两个控制台语句之间睡3秒。它使代码保持与传统风格一样漂亮。棘手的是在睡眠中常规。它将调用函数体读取为字符串并将其分为两部分。拆下上部并通过下部创建另一个功能。在等待指定的毫秒数后,它通过应用原始上下文和参数来调用创建的函数。对于原始流程,它将以&#34; return&#34;结束。照常。对于&#34;产量&#34;?它用于正则表达式匹配。这是必要的,但完全没用。

它完全不是100%完美,但它至少可以完成我的工作。我必须提到使用这段代码的一些限制。由于代码分为两部分,&#34;返回&#34;语句必须在外部,而不是在任何循环或{}中。即。

function coroutine3() {
    this.a = 100;
    console.log('coroutine3-1:start');
    if(true) {
        return sleepFor(3000).yield;
    } // <- raise exception here
    console.log('coroutine3-2:complete');
    this.a++;
}

上述代码必须有问题,因为在创建的函数中,近括号不能单独存在。另一个限制是由&#34; var xxx = 123&#34;声明的所有局部变量。无法承担下一个功能。你必须使用&#34; this.xxx = 123&#34;实现同样的目标。如果你的函数有参数并且它们有变化,那么修改后的值也无法进入下一个函数。

function coroutine4(x) { // assume x=abc
    var z = x;
    x = 'def';
    console.log('coroutine4-1:start' + z + x); //z=abc, x=def
    return sleepFor(3000).yield;
    console.log('coroutine4-2:' + z + x); //z=undefined, x=abc
}

我会介绍另一个函数原型:waitFor

waitFor = function(check, ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?waitFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    var thread = setInterval(function() {
        if(check()) {
            clearInterval(thread);
            new Function(funcArgs, funcBody).apply(context, args);
        }
    }, ms?ms:100);
    return this;
}

等待&#34;检查&#34;函数,直到它返回true。它每100ms检查一次值。您可以通过传递其他参数来调整它。考虑测试协程2:

function coroutine2(c) {
    /* some codes here */
    this.a = 1;
    console.log('coroutine2-1:' + this.a++);
    return sleepFor(500).yield;

    /* next */
    console.log('coroutine2-2:' + this.a++);
    console.log('coroutine2-2:waitFor c.a>100:' + c.a);
    return waitFor(function() {
        return c.a>100;
    }).yield;

    /* the rest of code */
    console.log('coroutine2-3:' + this.a++);
}

到目前为止,我们也喜欢漂亮的风格。其实我讨厌嵌套的回调。很容易理解,coroutine2将等待coroutine1的完成。有趣?好的,然后运行以下代码:

this.a = 10;
console.log('outer-1:' + this.a++);
var c1 = new coroutine1();
var c2 = new coroutine2(c1);
console.log('outer-2:' + this.a++);

输出结果为:

outer-1:10
coroutine1-1:start
coroutine2-1:1
outer-2:11
coroutine2-2:2
coroutine2-2:waitFor c.a>100:100
coroutine1-2:complete
coroutine2-3:3

在初始化的coroutine1和coroutine2之后立即完成外部。然后,coroutine1将等待3000ms。在等待500ms后,Coroutine2将进入步骤2。之后,一旦检测到coroutine1.a值> 1,它将继续步骤3。 100。

要注意有3个上下文来保存变量&#34; a&#34;。一个是外部的,其值是10和11.另一个是在coroutine1中,其值是100和101.最后一个是在coroutine2中,其值是1,2和3.在coroutine2中,它还等待来自ca的ca来自coroutine1,直到其值大于100. 3个上下文是独立的。

复制和粘贴的完整代码:

sleepFor = function(ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?sleepFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    setTimeout(function() {
        new Function(funcArgs, funcBody).apply(context, args);
    }, ms);
    return this;
}

waitFor = function(check, ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?waitFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    var thread = setInterval(function() {
        if(check()) {
            clearInterval(thread);
            new Function(funcArgs, funcBody).apply(context, args);
        }
    }, ms?ms:100);
    return this;
}

function coroutine1() {
    this.a = 100;
    console.log('coroutine1-1:start');
    return sleepFor(3000).yield;
    console.log('coroutine1-2:complete');
    this.a++;
}

function coroutine2(c) {
    /* some codes here */
    this.a = 1;
    console.log('coroutine2-1:' + this.a++);
    return sleepFor(500).yield;

    /* next */
    console.log('coroutine2-2:' + this.a++);
    console.log('coroutine2-2:waitFor c.a>100:' + c.a);
    return waitFor(function() {
        return c.a>100;
    }).yield;

    /* the rest of code */
    console.log('coroutine2-3:' + this.a++);
}

this.a = 10;
console.log('outer-1:' + this.a++);
var c1 = new coroutine1();
var c2 = new coroutine2(c1);
console.log('outer-2:' + this.a++);

在IE11和Chrome49中进行了测试。因为它使用arguments.callee,所以如果它以严格模式运行可能会有麻烦。

答案 51 :(得分:1)

有一个新的库,它可以整齐地将功能与超时联系在一起,这样你就可以避免回调地狱。

Sequencr.js

转过来:

setTimeout(function(timeout){
    function1();
    setTimeout(function(timeout){
        function2();
        setTimeout(function(timeout){
            function3();
        }, timeout, timeout)
    }, timeout, timeout)
}, 10, 10);

进入这个:

Sequencr.chain([function1, function2, function3], 10);

并且内置支持循环&#34;睡眠&#34;每次迭代之间。

答案 52 :(得分:1)

需要使用“睡眠”方法的对象的方法,如下所示:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function () {
    this.DoSomething1(arg1);
    sleep(500);
    this.DoSomething2(arg1);
}

几乎可以翻译成:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function (arg1) {
    var self = this;
    self.DoSomething1(arg1);
    setTimeout(function () {
        self.DoSomething2(arg1);
    }, 500);
}

不同之处在于“SomeMethod”的操作在执行“DoSomething2”操作之前返回。 “SomeMethod”的调用者不能依赖于此。由于“Sleep”方法不存在,我使用后面的方法并相应地设计我的代码。

我希望这会有所帮助。

答案 53 :(得分:1)

如果确实想要暂停脚本,您可以这样做:

var milliseconds;
var pretime;
var stage;

function step(time){
  switch(stage){
    case 0:
      //Code before the pause

      pretime=time;
      milliseconds=XXX;
      stage=1;
      break;
    case 1:
      //Code that is looped through while paused

      if(time-pretime >= milliseconds){
        //Code after the pause

        pretime=time;
        milliseconds=XXX;
        stage=2;
      }
      break;
    case 2:
      //Code that is looped through while paused

      if(time-pretime >= milliseconds){
        //Code after the pause

        pretime=time;
        milliseconds=XXX;
        stage=3;
      }
      break;
    case 3:
      //Etc...
  }

  Window.requestAnimationFrame(step)
}

step();

如果您仍然使用循环,这可能正是您想要的,并且您可以通过多种方式更改它,以便您有一些功能等待一段时间而其他功能正常运行。我一直都在使用纯JS游戏。

答案 54 :(得分:1)

<块引用>

sleep() 的 JavaScript 版本是什么?

这已经在 the currently accepted answer 中得到了回答:

await new Promise(r => setTimeout(r, 1000));

两个异步函数同时运行

最好把它放在函数sleep()中,然后 await sleep()
要使用它,需要一些上下文:

function sleep (ms) { return new Promise(r => setTimeout(r, ms)); }

(async function slowDemo () {
  console.log('Starting slowDemo ...');
  await sleep(2000);
  console.log('slowDemo: TWO seconds later ...');
})();

(async function fastDemo () {
  console.log('Starting fastDemo ...');
  await sleep(500);
  for (let i = 1; i < 6; i++) {
    console.log('fastDemo: ' + (i * 0.5) + ' seconds later ...');
    await sleep(500);
  }
})();
.as-console-wrapper { max-height: 100% !important; top: 0; }

两个异步调用依次运行——一个接一个

但是假设 slowDemo 产生的结果是 fastDemo 取决于。
在这种情况下,slowDemo 必须在 fastDemo 开始之前运行完成:

function sleep (ms) { return new Promise(r => setTimeout(r, ms)); }

(async () => {
  await (async function slowDemo () {
    console.log('Starting slowDemo ...');
    await sleep(2000);
    console.log('slowDemo: TWO seconds later ... completed!');
  })();

  (async function fastDemo () {
    console.log('Starting fastDemo ...');
    await sleep(500);
    let i = -2;
    for (i = 1; i < 5; i++) {
      console.log('fastDemo: ' + (i * 0.5) + ' seconds later ...');
      await sleep(500);
    }
    console.log('fastDemo: ' + (i * 0.5) + ' seconds later. Completed!');
  })();
})();
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 55 :(得分:1)

如果您希望代码可在所有浏览器上使用,请使用 setTimeout()clearTimeout()。如果您正在深入阅读答案,您可能会注意到接受的答案破坏了 Internet Explorer 11 中的所有 JavaScript 编译,并且在使用此解决方案后,5%用户大约仍在使用这种积极开发的浏览器并需要支持。

这几乎破坏了一切。有已知的关于箭头函数破坏 DrupalWordPressAmazon AWSIBM 软件的 IE11 功能的报告,甚至在 {{3 }}。

检查一下...

StackOverflow

Browser Compatibility Chart - Arrow Function Expressions

使用 setTimeout()clearTimeout(),这将适用于所有浏览器......

Browser Compatibility Chart - setTimeout

var timeout;

function sleep(delay) {
        if(timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
            myFunction();
        }, delay);
}
  
console.log("sleep for 1 second");
sleep(1000);

function myFunction() {
  console.log("slept for 1 second!");
}

答案 56 :(得分:0)

JavaScript 是一个单线程执行环境。那里的每个函数都只由一个线程执行。要求“睡眠”意味着您希望将整个 VM 实例暂停那么多(毫秒)秒,我认为这在 JavaScript 世界中并不是一个非常现实的要求,因为不仅是那个特定的函数,还有其余的如果执行线程进入睡眠状态,所有执行都会受到影响。

首先,实际上不可能使该线程休眠。您只能通过投入一些无所事事的工作来尝试使该线程保持忙碌。但是,如果您只想在某些计算中添加延迟,请将它们的执行放在单个函数上下文中,并让继续发生在该函数内的 setTimeout(或 Promise,如果您愿意)内。如果通过睡眠,您希望延迟某些事情,否则,这是不可能的。

答案 57 :(得分:0)

I had a similar problem, having to wait for control existence and checking in intervals. Since there is no real sleep, wait or pause in JavaScript and using await / async is not supported properly in Internet Explorer, I made a solution using setTimeOut and injecting the function in case of successfully finding the element. Here is the complete sample code, so everyone can reproduce and use it for their own project:

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
        var ElementSearchStatus = {
            None: 0,
            Found: 1,
            NotFound: 2,
            Timeout: 3
        };

        var maxTimeout = 5;
        var timeoutMiliseconds = 1000;

        function waitForElement(elementId, count, timeout, onSuccessFunction) {
            ++count;
            var elementSearchStatus = existsElement(elementId, count, timeout);
            if (elementSearchStatus == ElementSearchStatus.None) {
                window.setTimeout(waitForElement, timeoutMiliseconds, elementId, count, timeout, onSuccessFunction);
            }
            else {
                if (elementSearchStatus == ElementSearchStatus.Found) {
                    onSuccessFunction();
                }
            }
        }

        function existsElement(elementId, count, timeout) {
            var foundElements = $("#" + elementId);
            if (foundElements.length > 0 || count > timeout) {
                if (foundElements.length > 0) {
                    console.log(elementId + " found");
                    return ElementSearchStatus.Found;
                }
                else {
                    console.log("Search for " + elementId + " timed out after " + count + " tries.");
                    return ElementSearchStatus.Timeout;
                }
            }
            else {
                console.log("waiting for " + elementId + " after " + count + " of " + timeout);
                return ElementSearchStatus.None;
            }
        }

        function main() {
            waitForElement("StartButton", 0, maxTimeout, function () {
                console.log("found StartButton!");
                DoOtherStuff("StartButton2")
            });
        }

        function DoOtherStuff(elementId) {
            waitForElement(elementId, 0, maxTimeout, function () {
                console.log("found " + elementId);
                DoOtherStuff("StartButton3");
            });
        }
    </script>
</head>
<body>
    <button type="button" id="StartButton" onclick="main();">Start Test</button>
    <button type="button" id="StartButton2" onclick="alert('Hey ya Start Button 2');">Show alert</button>
</body>
</html>

答案 58 :(得分:0)

一种非常简单的睡眠方法,它将与运行Javascript的任何程序兼容...该代码已经过500项测试,但在我的Web浏览器上仍然看不到CPU和内存使用情况。

这里有一个函数等待节点可见...

此函数创建一个新的上下文function () {}以避免递归。我们在新上下文中放置了与调用者代码相同的代码。几秒钟后,我们使用函数Timeout来调用我们的函数。

var get_hyper = function (node , maxcount , only_relation) {
    if (node.offsetParent === null) {
            // node is hidden
            setTimeout(function () { get_hyper(node , maxcount , only_relation)}
                      ,1000);
            return;
    };

    // Enter here the code that wait that that the node is visible
    // before getting executed.

};

答案 59 :(得分:0)

我得到Promise不是使用最佳答案的构造函数。如果导入蓝鸟,则可以执行此操作。最简单的解决方案imo。

import * as Promise from 'bluebird';


  await Promise.delay(5000)

答案 60 :(得分:0)

使用实际的睡眠功能的问题是JavaScript是单线程的,并且睡眠功能将使您的浏览器选项卡在该时间内挂起。

答案 61 :(得分:0)

2019年更新,使用Atomics.wait

应该在Node 9.3或更高版本中工作。

我在Node.js中需要一个非常准确的计时器,因此非常有用。 但是,似乎浏览器中的支持非常有限。

let ms = 10000;
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);

运行10秒计时器基准测试。

使用setTimeout时,我得到最多7000微秒的错误。 (7毫秒)

使用Atomics,我的错误似乎保持在600微秒以下。 (0.6毫秒)

答案 62 :(得分:0)

2021+ 更新

如果您正在寻找替代方案:

let sleep = ms => new Promise(res=>setTimeout(res,ms));

然后使用这个:

let sleep = async ms => void await Atomics.waitAsync(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms).value;

请注意,在发布此问题时,它是第 3 阶段提案。此外,它可能要求您的站点跨域隔离。要查看它是否适用于您的浏览器,(在 Stack Overflow 上)试试这个:

let sleep = async ms => void await Atomics.waitAsync(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms).value;

void async function() {
  console.log(1);
  await sleep(2000);
  console.log(2);
}()

答案 63 :(得分:0)

使用承诺

的单行
const sleep = t => new Promise(s => setTimeout(s, t));

演示

const sleep = t => new Promise(s => setTimeout(s, t));
// usage
async function demo() {
    // count down
    let i = 6;
    while (i--) {
        await sleep(1000);
        console.log(i);
    }
    // sum of numbers 0 to 5 using by delay of 1 second
    const sum = await [...Array(6).keys()].reduce(async (a, b) => {
        a = await a;
        await sleep(1000);
        const result = a + b;
        console.log(`${a} + ${b} = ${result}`);
        return result;
    }, Promise.resolve(0));
    console.log("sum", sum);
}
demo();

答案 64 :(得分:0)

我认为这个问题很好,并指出了重要的观点和注意事项。

话虽如此,我认为问题的核心在于意图和了解开发人员(您)想要控制什么。

首先,名称sleep是重载的命名选择。即“什么”将被“睡眠”;和作为开发人员的“什么”我可以控制?

在运行于任何OS进程,任何裸机或托管系统上的任何语言引擎中,“开发人员”均不受OS-shared资源的控制(所有者)除非它们是编写OS / Process系统本身,否则CPU核心[和/或线程]。 CPU是分时资源,工作执行进度的货币是在系统上要执行的所有工作中分配的“周期”。

作为应用程序/服务开发人员,最好考虑我可以控制由os-process / language-engine管理的工作流活动流。在某些系统上,这意味着我控制本地操作系统线程(可能共享CPU内核);在其他系统上,这意味着我控制了 async-continuation-workflow链/树

对于JavaScript,是“后期”。

因此,当需要“睡眠”时,我打算使我的工作流在执行之前继续执行下一个“步骤”(阶段/活动/任务)的过程中被“延迟”执行一段时间。工作流程。

这是“适当地”的说法,作为开发人员,(考虑)模型作为线性代码流是最容易的。依靠工作流的组成按需扩展。

如今,在JavaScript中,我们可以选择使用基于1980年代基于角色的高效多任务连续架构来设计此类线性工作流程 (重新标记为现代Future / Promises / then / await等)

考虑到这一点,我的回答是不是提供技术解决方案,而是专注于意图在问题本身中进行设计 透视

我建议任何答案都应首先考虑以上概念,然后选择一个可以提醒并提示意图的名称(sleep除外)。

工作流程

  • 选择1:delayWorkForMs(nMsToDelay)
  • 选择2:delayAsyncSequenceForMs(msPeriod)
async delayAsyncSequenceForMs(msPeriod) {
  await new Promise(resolve => setTimeout(resolve, msPeriod));
}

请注意,任何async 函数 总是都会返回Promiseawait只能在{ {1}} 功能
(大声笑,你可能会问自己为什么...)

  • 注意事项1:请勿使用“循环”来增加CPU周期。
  • 注意事项2:在JavaScript模型中,当您在非异步函数中时,您无法“延迟”(等待)“异步”工作流程的执行(除非您做的不好,而不必要地消耗cpu周期)。您只能在“异步”功能中“延迟”代码步骤。
    在内部,“异步”功能被建模为每个async 关键字处入口点/继续的集合。如果您熟悉反引号插值模型,则可以像在编写反引号字符串一样,在概念上建模“认为等待”,例如:
await

答案 65 :(得分:0)

内联:

(async () => await new Promise(resolve => setTimeout(resolve, 500)))();

此处的 500 是 VM 在移动到下一行代码之前将等待的毫秒数。

答案 66 :(得分:0)

在sleep方法中,您可以返回任何then-able对象。不一定是新的承诺。

示例:

const sleep = (t) =>  ({ then: (r) => setTimeout(r, t) })

const someMethod = async () => {

    console.log("hi");
    await sleep(5000)
    console.log("bye");
}

someMethod()

答案 67 :(得分:0)

保持主线程忙几毫秒:

function wait(ms) {
  const start = performance.now();
  while(performance.now() - start < ms);
}

答案 68 :(得分:0)

在某些情况下,一个很好的选择是显示顶级消息面板以停止用户交互,然后在获得等待(异步)结果时再次隐藏它。这样浏览器就可以继续执行后台任务,但会暂停工作流程,直到您的结果恢复为止。

答案 69 :(得分:0)

我使用多线程HTML5 Worker,它将能够中止指向无响应URL的同步XMLHttpRequest。这不会阻止浏览器。

https://gist.github.com/el-gringo/6990785

答案 70 :(得分:0)

简短的回答是 NO ,而不是javascript本身。您的解决方案似乎是不将控制权返回环境的唯一方法。

如果环境不支持事件,则必须执行此操作。他们可能也不会支持settimeout。

如果您处于事件驱动的环境(如浏览器或node.js),则settimeout绝对是最佳方式。

答案 71 :(得分:0)

总结(就像之前的答案中所述):

JavaScript中没有内置的睡眠功能。您应该使用setTimeoutsetInterval来达到类似的效果。

如果您真的想要,可以使用for循环模拟睡眠功能,例如原始问题中显示的那个,但这会让您的CPU像疯了一样工作。在Web Worker内部,另一种解决方案是对非响应IP进行同步XMLHttpRequest并设置适当的超时。这样可以避免CPU利用率问题。这是一个代码示例:

// Works only inside a web worker

function sleep(milliseconds) {
	var req = new XMLHttpRequest();
	req.open("GET", "http://192.0.2.0/", false);
	req.timeout = milliseconds;
	try {
		req.send();
	} catch (ex) {
		
	}
}

console.log('Sleeping for 1 second...');
sleep(1000);
console.log('Slept!');

console.log('Sleeping for 5 seconds...')
sleep(5000);
console.log('Slept!');

答案 72 :(得分:0)

在服务器端,您可以使用deasync sleep()方法,该方法在 C 中原生实现,因此可以有效地实现等待效果不会阻止事件循环或使CPU处于100%负载状态。

示例:

#!/usr/bin/env node

// Requires `npm install --save deasync`
var sleep = require("deasync").sleep;

sleep(5000);

console.log ("Hello World!!");

但是,如果你需要一个 javascript函数(例如,通过浏览器在客户端运行它),我很抱歉地说我认为你的{{1函数是接近它的唯一方法,而不仅仅是:

  1. 不仅会暂停您的功能,还会暂停整个事件循环。因此,不会参加任何其他活动。

  2. 它使你的cpu处于100%负载状态。

  3. 所以,如果你需要它用于浏览器脚本并且不想要那些可怕的效果,我必须说你应该重新考虑你的功能:

    A)。您可以在超时时调用它(或调用pausecomp()函数)。如果您不希望功能产生任何结果,则更容易。

    B)。或者,如果你需要等待结果,那么你应该转向使用promises(或者回调地狱,当然; - ))。

    没有结果预期的例子:

    do_the_rest()

    返回承诺的示例(请注意它会改变您的函数用法):

    function myFunc() {
    
        console.log ("Do some things");
    
        setTimeout(function doTheRest(){
            console.log ("Do more things...");
        }, 5000);
    
        // Returns undefined.
    };
    
    
    myFunc();
    

答案 73 :(得分:0)

我已经有这个问题了很长时间,我需要的答案并不完全是这里提供的。此等待函数会导致同步等待,但不会占用cpu。 waitForIt向任何地方发出ajax请求,并将async标志设置为false。 waitF对一个帧执行相同的操作,而waitD对div执行相同的操作。 Ajax大约需要100毫秒,帧大约是25,div大约是1.等待函数根据你给它的时间来利用所有这些。如果它没有等待足够长的话,那就再做一次。在处理多个异步加载元素时我需要这个。基本上是'等到这个元素存在'。你可以在这里玩它https://jsfiddle.net/h2vm29ue/它只是利用浏览器自然等待的东西。更长的版本https://jsfiddle.net/5cov1p0z/32/更精确。

 function waitForIt() {
     var start = new Date();
     var xhttp = new XMLHttpRequest();
     xhttp.onreadystatechange = function() {
         if (this.readyState == 4 && this.status == 200) {
            //doesn't matter
         }
     };
     xhttp.open("GET", "WaitForIt", false);
     xhttp.send();
     var end = new Date();
 }
 //



 function waitF() {
     var start = new Date();
     var ifram = document.createElement('iframe');
     ifram.id = 'ifram';
     ifram.src = '';
     var div = document.createElement('div');
     div.id = 'timer';
     document.body.appendChild(div);
     document.getElementById('timer').appendChild(ifram);
     document.getElementById('timer').removeChild(ifram);
     document.body.removeChild(div);
     var end = new Date();
     return (end - start);
 }


 function waitD() {
     var start = new Date();
     var div = document.createElement('div');
     div.id = 'timer';
     document.body.appendChild(div);
     div.click();
     document.body.removeChild(div);
     var end = new Date();
     return (end - start);
 }

 function wait(time) {
     var start = new Date();
     var end = new Date();
     while ((end - start < time)) {

         if ((time - (end - start)) >= 200) {
             waitForIt();
         } else {
             if ((time - (end - start)) >= 50) {
                 waitF();
             } else {
                 waitD();
             }

         }
         end = new Date();
     }
     return (end - start);
 }

答案 74 :(得分:0)

Javascript函数不允许暂停。用同步Javascript程序实现。程序等待I / O操作和睡眠超时。适用于javascript 1.7。

演示: demo sleep demo suspendable procedures

答案 75 :(得分:-1)

使用三个功能:

  1. 调用setInterval启动循环的函数
  2. 调用clearInterval停止循环,然后调用setTimeout进入睡眠状态,最后调用setTimeout作为回调重启循环的函数
  3. 跟踪迭代次数,设置睡眠数和最大数的循环,一旦达到睡眠数就调用睡眠功能,并在达到最大数量后调用clearInterval
  4. var foo = {};
    
    function main()
      {
      'use strict';
      /*Initialize global state*/
      foo.bar = foo.bar || 0;
      /* Initialize timer */ 
      foo.bop = setInterval(foo.baz, 1000); 
      }
     
     sleep = 
          function(timer)
          {
          'use strict';
          clearInterval(timer);
          timer = setTimeout(function(){main()}, 5000);
          };
           
     
     foo.baz = 
       function()
          {
          'use strict';
          /* Update state */
          foo.bar = Number(foo.bar + 1) || 0; 
          /* Log state */
          console.log(foo.bar);
          /* Check state and stop at 10 */ 
          (foo.bar === 5) && sleep(foo.bop);
          (foo.bar === 10) && clearInterval(foo.bop);
          };
          
    main();

    Event Loop

    <强>参考

答案 76 :(得分:-1)

在Livescript(编译为Javascript)中,您可以执行以下操作:

sleep = (ms, func) -> set-timeout func, ms

console.log "hello-1"
<- sleep 2000ms
console.log "hello-2"
<- sleep 2000ms
console.log "hello-3"

答案 77 :(得分:-1)

另一种可能的方式是:

var _timer;
clearTimeout(_timer);
_timer = setTimeout(function() {
    // Your code
}, 1000); // Delay for 1 s.

答案 78 :(得分:-1)

我最近有一个案例,即在$.ui.popup的回调执行之前,回调后的代码正在执行。我的解决方案是在设置一个名为pause之前的var,将其设置为true,执行$.ui.popup代码,然后让我需要在一个间隔中等待的代码。例如:

var pause = false;
function something() {
    if(edited && renamed) {
        pause = true;
        $.ui.popup({
            //...
            doneCallback: function() {
                //...
                pause = false;
            }
            //...
        });
        //...
    }

    var waitCode = setInterval(function(){
        if(!pause) {
            //... code I needed to wait on ...
            clearInterval(waitCode);
        }
    },500);
}

答案 79 :(得分:-1)

我确信有一百万种方法可以做得更好,但我想我会尝试创建一个对象:

// execute code consecutively with delays (blocking/non-blocking internally)
function timed_functions() 
{
this.myfuncs = [];
this.myfuncs_delays = []; // mirrors keys of myfuncs -- values stored are custom delays, or -1 for use default
this.myfuncs_count = 0; // increment by 1 whenever we add a function
this.myfuncs_prev   = -1; // previous index in array
this.myfuncs_cur    = 0; // current index in array
this.myfuncs_next  = 0; // next index in array
this.delay_cur     = 0; // current delay in ms
this.delay_default = 0; // default delay in ms
this.loop = false;      // will this object continue to execute when at end of myfuncs array?
this.finished = false;  // are we there yet?
this.blocking = true;   // wait till code completes before firing timer?
this.destroy = false;   // <advanced> destroy self when finished


this.next_cycle = function() {
var that  = this;
var mytimer = this.delay_default;

if(this.myfuncs_cur > -1)
if(this.myfuncs_delays[this.myfuncs_cur] > -1)
mytimer = this.myfuncs_delays[this.myfuncs_cur];

console.log("fnc:" + this.myfuncs_cur);
console.log("timer:" + mytimer);
console.log("custom delay:" + this.myfuncs_delays[this.myfuncs_cur]);
setTimeout(function() {
// times up! next cycle...
that.cycle(); 

}, mytimer);
}

this.cycle = function() {

// now check how far we are along our queue.. is this the last function?
if(this.myfuncs_next + 1 > this.myfuncs_count)
{
if(this.loop)
{
console.log('looping..');
this.myfuncs_next = 0;
}
else
this.finished = true;
}


// first check if object isn't finished
if(this.finished)
return false;

// HANDLE NON BLOCKING //
if(this.blocking != true) // blocking disabled
{
console.log("NOT BLOCKING");
this.next_cycle();
}


// set prev = current, and current to next, and next to new next
this.myfuncs_prev = this.myfuncs_cur;
this.myfuncs_cur  = this.myfuncs_next;
this.myfuncs_next++; 

// execute current slot
this.myfuncs[this.myfuncs_cur]();




// HANDLE BLOCKING
if(this.blocking == true)  // blocking enabled
{
console.log("BLOCKING");
this.next_cycle();
}




return true;
};

// adders 
this.add = {
that:this,

fnc: function(aFunction) { 
// add to the function array
var cur_key = this.that.myfuncs_count++;
this.that.myfuncs[cur_key] = aFunction;
// add to the delay reference array
this.that.myfuncs_delays[cur_key] = -1;
}
}; // end::this.add

// setters
this.set = {
that:this, 

delay:          function(ms)    {  
var cur_key = this.that.myfuncs_count - 1;
// this will handle the custom delay array this.that.myfunc_delays
// add a custom delay to your function container

console.log("setting custom delay. key: "+ cur_key + " msecs: " + ms);
if(cur_key > -1)
{ 
this.that.myfuncs_delays[cur_key] = ms; 
}

// so now we create an entry on the delay variable
},  

delay_cur:      function(ms)    { this.that.delay_cur = ms;         },
delay_default:  function(ms)    { this.that.delay_default = ms;         },
loop_on:          function()        { this.that.loop = true; }, 
loop_off:         function()        { this.that.loop = false; },
blocking_on:      function()        { this.that.blocking = true; }, 
blocking_off:     function()        { this.that.blocking = false; },

finished:           function(aBool) { this.that.finished = true; }
}; // end::this.set    


// setters
this.get = {
that:this, 

delay_default: function() { return this.that.delay_default; },
delay_cur:     function() { return this.that.delay_cur; }
}; // end::this.get     

} // end:::function timed_functions()

并使用如下:     // // BEGIN :: TEST // // //

// initialize
var fncTimer = new timed_functions;

// set some defaults
fncTimer.set.delay_default(1000);
fncTimer.set.blocking_on();
// fncTimer.set.loop_on();
// fncTimer.set.loop_off();


// BEGIN :: ADD FUNCTIONS (they will fire off in order)
fncTimer.add.fnc(function() {
    console.log('plan a (2 secs)');
});
fncTimer.set.delay(2000); // set custom delay for previously added function

fncTimer.add.fnc(function() {
    console.log('hello world (delay 3 seconds)');
});
fncTimer.set.delay(3000);

fncTimer.add.fnc(function() {
    console.log('wait 4 seconds...');
});
fncTimer.set.delay(4000);

fncTimer.add.fnc(function() {
    console.log('wait 2 seconds');
});
fncTimer.set.delay(2000);

fncTimer.add.fnc(function() {
    console.log('finished.');
});
// END :: ADD FUNCTIONS


// NOW RUN
fncTimer.cycle(); // begin execution 


// // // END :: TEST // // //

答案 80 :(得分:-1)

我更喜欢这种功能样式 sleep功能:

const sleep = ms =>
    Promise(resolve => setTimeout(resolve, ms))

答案 81 :(得分:-2)

这是一种在.hta脚本中休眠的方法,这样当脚本唤醒时,它会按顺序执行下一个命令,这在循环中是必需的。这是一个真正的睡眠;它不会让睡眠时处理器忙。例如。处理器能够在睡眠期间下载和呈现页面。

只需一次,在代码的开头附近,去

var WSHShell = new ActiveXObject ("WScript.Shell");

对于睡眠,例如1秒= 1000毫秒,执行语句

WSHShell.Run ('Sleep.js 1000', 3, true);

在与脚本相同的目录中是文件Sleep.js,其中包含以下一行:

WScript.Sleep (WScript.Arguments (0));

(注意; 0在括号中,而不是括号。)后者是实际执行睡眠的行。前面代码段中的参数true使调用同步。前面的参数中的3似乎没有任何效果,但你需要一些参数,以便true是第三个参数。微软称“WScript对象......在调用其属性和方法之前永远不需要实例化,并且它总是可以从任何脚本文件中获得。”,但事实并非如此。它可以在一个独立的.js文件中使用,如上所述,但显然不在.js文件使用的.hta文件中,所以这就是为什么它必须在一个单独的文件中文件,如上所述调用。

答案 82 :(得分:-2)

现在也可以使用本机模块util来实现常规同步功能。

const { promisify } = require('util')
const sleep = promisify(setTimeout)

module.exports = () => {
  await someAsyncFunction()
  await sleep(2000)
  console.log('2 seconds later...')
}

答案 83 :(得分:-3)

我可能会有点迟到,有点懒惰,有点无聊或有点干扰或有点像“大嘴背”,但是......

到目前为止我读过的每一个和任何解决方案都会像“让我们睡觉,看看明天发生了什么”。

setInterval(callback,time)将等待很长时间,然后调用回调,WHILE阻塞运行时。 “setInterval”的当前实现远不是线程保存,甚至不介意并发。

虽然提到的稀疏解决方案看起来像猜测,C#(),但它们仍然不像C#/ .NET那样工作。他们仍然像在C中一样工作。

JavaScript目前不提供实现真正多线程的架构。最好的方法是TypeScript,但仍然缺乏这么多真正的解决方案,它会......伤害。 JavaScript,jQuery,AJAX,jNode,甚至TypeScript只是依赖于实现者情绪的商品和坏处的一堆Wannabes。事实。完全停止。

答案 84 :(得分:-4)

这可能有用。它在c和javascript中为我工作。

function sleep(time) {
 var x = 0;
 for(x = 0;x < time;x++) {/* Do nothing*/}
}

答案 85 :(得分:-5)

var waitTillSomethingHappens = function(){  
    if(somethingHappened == 1)  
    {  
        alert('Something Happened get out of sleep');  
    }
    else
    {  
    setTimeout(waitTillSomethingHappens,1000);  
    }  
};

答案 86 :(得分:-6)

或者只是创建它:

function yourFunction(){

   //do something
   setInterval(myFunc(),1000);
   //do something else

}

function myFunc(){
   return;
}

这将等待指定的间隔并调用该函数,该函数将不执行任何操作。