有没有比下面的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+)
使用三种功能:
调用setInterval启动循环的函数一个函数,它调用clearInterval来停止循环,然后调用setTimeout来休眠,最后在setTimeout内调用作为回调来重新启动循环一个循环,跟踪迭代次数,设置睡眠次数和最大次数,一旦达到睡眠次数就调用睡眠函数,并在达到最大次数后调用clearInterval
var foo={};函数main(){“使用严格”;/*初始化全局状态*/foo.bar=foo.bar ||0;/*初始化计时器*/foo.bop=设置间隔(foo.baz,1000);}睡眠=功能(计时器){“使用严格”;clearInterval(计时器);timer=setTimeout(function(){main()},5000);};foo.baz=函数(){“使用严格”;/*更新状态*/foo.bar=数字(foo.bar+1)||0;/*日志状态*/console.log(foo.bar);/*检查状态并在10时停止*/(foo.bar===5)&&睡眠(foo.bop);(foo.bar==10)&&clearInterval(foo.bop);};main();
工具书类
使用JavaScript开发游戏为什么iOS 8中的滚动事件更改是一件大事Ember.js中的实时轮询系统使用requestAnimationFrame()驱动动画MDN:JavaScript并发模型和事件循环网格研究:Node.js在JavaScript中超过60fps第2部分:不阻塞单个线程的CPU密集型JavaScript计算
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){}
%>