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

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

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


当前回答

在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!
});

其他回答

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

在许多情况下,它可以使用promise(Ajax请求通用)。它们允许您以同步方式进行异步操作。还有成功/失败的处理,它们可以被链接起来。

它们是ECMAScript 6的一部分,所以浏览器支持还不完全,主要是Internet Explorer不支持它们。还有一个名为Q的库,用于实现承诺。

参考文献:

JavaScript承诺:简介ES6 Promise:ES6风格Promise的polyfill(Shim适用于旧版浏览器或Internet Explorer浏览器)

为了测试,我需要一段忙碌的等待。我不想拆分代码,因为这需要很多工作,所以一个简单的for为我做了这件事。

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

我看不出这样做有什么坏处,这对我来说很有好处。

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

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

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

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游戏中使用这个。

内联函数:

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

500是VM在移动到下一行代码之前等待的时间(以毫秒为单位)。

tldr位;

基本上,当您创建一个promise时,它会在创建时返回一个可观察到的值,在回调中提供一个解析引用,用于在数据/响应可用时移交数据/响应。在这里,在500ms后通过setTimeOut调用resolve,直到未执行resolve之前,外部作用域正在等待进一步的处理,因此,创建了一个伪块。这与非阻塞(或调用其他语言中可用的非线程保留睡眠)完全不同,因为线程和最可能的UI以及网页/节点应用程序的任何其他正在进行的任务将被阻塞,而主线程将专门用于等待承诺解决。