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

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

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


当前回答

等待支持和蓝鸟承诺:

await bluebird.delay(1000);

这将像C语言的同步休眠(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();

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

首先,应该使用setTimeout和setInterval,因为JavaScript具有回调性质。如果您想使用sleep(),则是控制流或代码架构不正确。

尽管如此,我想我仍然可以帮助实现两个睡眠。

1.我头顶上的假同步跑步:

// A module to do that //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.实际同步运行

有一天,我对它进行了很多思考,我在JavaScript中真正睡觉的唯一想法就是技术。

睡眠函数必须是同步Ajax调用,超时设置为睡眠值。这就是真正睡觉的唯一方法。

我会将setTimeOut封装在Promise中,以实现与其他异步任务的代码一致性:Fiddle中的Demo

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

它的用法如下:

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

如果您习惯使用Promise,那么很容易记住语法。

有一个新的库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);

并且内置支持在每次迭代之间“休眠”的循环。

在JavaScript中,我重写了每个函数,以便它能够尽快结束。您希望浏览器恢复控制,以便它可以更改DOM。

每次我想在函数中间休眠时,我都会重构以使用setTimeout()。

Edit

任何语言中臭名昭著的睡眠或延迟功能都备受争议。有些人会说,应该总是有一个信号或回调来启动给定的功能,而另一些人会认为,有时任意的延迟时间是有用的。我说,每个人都有自己的规则,在这个行业中,一条规则永远无法支配任何事情。

编写睡眠函数很简单,而且使用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!
});