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

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

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


当前回答

在sleep方法中,可以返回任何可执行的对象。不一定是新的承诺。

例子:

constsleep=(t)=>({then:(r)=>setTimeout(r,t)})常量someMethod=async()=>{console.log(“hi”);等待睡眠(5000)console.log(“再见”);}someMethod()

其他回答

2019更新使用Atomics.wait

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

我在Node.js中需要一个非常精确的计时器,它非常适合。

然而,浏览器中的支持似乎非常有限。

设ms=10000;Atomics.wait(新Int32Array(新SharedArray Buffer(4)),0,0,ms);

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

使用setTimeout,我得到的错误高达7000微秒(7毫秒)。

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

2020年更新:总结

function sleep(millis){ // Need help of a server-side page
  let netMillis = Math.max(millis-5, 0); // Assuming 5 ms overhead
  let xhr = new XMLHttpRequest();
  xhr.open('GET', '/sleep.jsp?millis=' + netMillis + '&rand=' + Math.random(), false);
  try{
    xhr.send();
  }catch(e){
  }
}

function sleepAsync(millis){ // Use only in async function
  let netMillis = Math.max(millis-1, 0); // Assuming 1 ms overhead
  return new Promise((resolve) => {
    setTimeout(resolve, netMillis);
  });
}
function sleepSync(millis){ // Use only in worker thread, currently Chrome-only
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, millis);
}

function sleepTest(){
  console.time('sleep');
  sleep(1000);
  console.timeEnd('sleep');
}

async function sleepAsyncTest(){
  console.time('sleepAsync');
  await sleepAsync(1000);
  console.timeEnd('sleepAsync');
}

function sleepSyncTest(){
  let source = `${sleepSync.toString()}
    console.time('sleepSync');
    sleepSync(1000);
    console.timeEnd('sleepSync');`;
  let src = 'data:text/javascript,' + encodeURIComponent(source);
  console.log(src);
  var worker = new Worker(src);
}

其中服务器端页面,例如sleep.jsp,看起来像:

<%
try{
  Thread.sleep(Long.parseLong(request.getParameter("millis")));
}catch(InterruptedException e){}
%>

从该链接获取的代码不会冻结计算机。但它只在Firefox中有效。

/**
 * 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 extension for Firefox.
     * Since Firefox 3, 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 finishes.
      */
    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);
    }
}

如果您想休眠一个匿名函数,就像您创建的处理程序一样,我建议您使用以下方法:

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

这段代码表示“如果等待条件尚未满足,请使用这些参数再次调用此函数。”。

另一种可能的方式是:

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

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

这几乎打破了一切。已知有报道称箭头函数破坏了Drupal、WordPress、Amazon AWS、IBM等软件的Internet Explorer 11功能,甚至在Stack Overflow上也有专门的讨论。

看看吧。。。

使用setTimeout()和clearTimeout(。。。

工作JSBin演示

var超时;功能休眠(延迟){if(超时){clearTimeout(超时);}timeout=setTimeout(函数){myFunction();},延迟);}console.log(“休眠1秒”);睡眠(1000);函数myFunction(){console.log(“睡眠了1秒钟!”);}