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

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

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


当前回答

如果您真的需要等待那么多秒,那么当前接受的使用async/await和setTimeout的解决方案是完美的。然而,如果您将其用于屏幕动画,则应该真正使用requestAnimationFrame()。此函数的功能与setTimeout非常相似,但回调仅在用户可见动画时调用。这意味着,如果您在网站上运行动画,并且用户切换选项卡,动画将暂停并节省电池寿命。

这里是使用requestAnimationFrame的wait方法的实现。它接收多个帧,并在它们全部通过后解析:

常量动画等待=(帧)=>新承诺((决心)=>{让framesPassed=0;requestAnimationFrame(函数循环(){如果(++framesPassed>=帧)返回resolve();requestAnimationFrame(循环);});});//演示用打字机效果const content=document.querySelector(“.content”);异步函数类型Writer(endText,等待){content.textContent=“”;for(const letter of endText){content.textContent+=字母;wait animationWait(等待);}}typeWriter(“好的。这个简单的打字机效果是requestAnimationFrame的一个例子。”,8);<p>动画将在下面播放;尝试切换选项卡并查看动画暂停。</p><code class=“content”></code>

阅读有关requestAnimationFrame的更多信息

浏览器支持(IE10+)

其他回答

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

出于对$DEITY的热爱,请不要使用忙等待睡眠功能。setTimeout和setInterval可以满足您的需要。

var showHide=document.getElementById('showHide');setInterval(()=>{showHide.style.visibility=“初始”;setTimeout(()=>{showHide.style.visibility=“隐藏”}, 1000);}, 2000); <div id=“showHide”>您好!再见</分区>

每隔两秒隐藏文本一秒。这显示了如何使用setInterval和setTimeout每秒显示和隐藏文本。

这里有一个使用同步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']);

现在用以下方式调用它:

sleep(5);

使用现有服务器实现

如果您没有自己的应用程序服务器(对于上面的PHP脚本),可以使用一些在线服务。例如:

函数睡眠(n){var request=new XMLHttpRequest();request.open('GET','http://httpstat.us/200?sleep='+n,假);request.send(空);};睡眠(1000);console.log(“一秒延迟完成”);

支持

关于为异步参数传递false,mdn注意到:

主线程上的同步请求很容易破坏用户体验,应该避免;事实上,许多浏览器已完全弃用主线程上的同步XHR支持。Workers中允许同步请求。

实际延迟时间

作为参数传递的毫秒数将是服务器在接收请求和发送响应之间等待的时间。传输和服务器负载所引起的延迟将被添加到其中。

你不能在JavaScript中做这样的睡眠,或者更确切地说,你不应该这样做。运行sleep或while循环将导致用户的浏览器挂起,直到循环完成。

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

这可以使用Java的睡眠方法来完成。我已经在Firefox和Internet Explorer中测试过它,它不会锁定计算机,不会占用资源,也不会导致无休止的服务器攻击。对我来说,这似乎是一个干净的解决方案。

首先,您必须在页面上加载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" />

然后,当您想要在JavaScript代码中轻松暂停时,您需要做的就是:

java.lang.Thread.sleep(xxx)

其中xxx是以毫秒为单位的时间。在我的案例中(作为理由),这是一家非常小的公司后端订单履行的一部分,我需要打印一张必须从服务器加载的发票。我是通过将发票(作为网页)加载到iFrame中,然后打印iFrame来完成的。

当然,我必须等到页面完全加载后才能打印,所以JavaScript代码必须暂停。我通过让发票页面(在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。