有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?

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

这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。


当前回答

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

其他回答

如果您使用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');

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

JavaScript sleep()或wait()

…还有一篇关于客户端解决方案的文章:JavaScript睡眠

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

对于希望将循环执行的一组调用隔开的特定情况,可以使用类似于下面代码的原型。如果没有原型,可以用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)
}

一个用于休眠的函数,使用同步调用让操作系统执行。使用您喜欢的任何操作系统休眠命令。在使用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

如果确实要暂停脚本,可以执行以下操作:

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();

如果您使用循环,这可能正是您想要的,并且您可以以某种方式对其进行更改,从而获得伪多线程,其中一些函数等待一段时间,其他函数正常运行。我一直在纯JavaScript游戏中使用这个。