有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。
我同意其他海报。忙着睡觉是个坏主意。
但是,setTimeout不支持执行。它在超时设置后立即执行函数的下一行,而不是在超时过期后执行,因此无法完成睡眠所能完成的任务。
方法是将你的功能分解为前后两部分。
function doStuff()
{
// Do some things
setTimeout(continueExecution, 10000) // Wait ten seconds before continuing
}
function continueExecution()
{
// Finish doing things after the pause
}
确保你的函数名仍然准确地描述了每一块正在做的事情(即GatherInputThenWait和CheckInput,而不是funcPart1和funcPart2)
此方法实现了在超时之后才执行您决定的代码行的目的,同时仍然将控制权返回到客户端PC,以执行它排队的任何其他代码。
正如评论中指出的那样,这绝对不会在循环中工作。你可以做一些花哨的(丑陋的)黑客来让它在一个循环中工作,但总的来说,这只会导致灾难性的意大利面条代码。
(见2016年更新答案)
我认为想要执行一个动作,等待,然后执行另一个动作是完全合理的。如果您习惯于用多线程语言编写,那么您可能会有一个想法,即在线程唤醒之前,在一定的时间内执行。
这里的问题是JavaScript是一个基于单线程事件的模型。虽然在特定情况下,让整个发动机等待几秒钟可能会很好,但一般来说这是不好的做法。假设我想在编写自己的函数时使用您的函数?当我调用你的方法时,我的方法都会冻结。如果JavaScript能够以某种方式保存函数的执行上下文,将其存储在某个地方,然后将其带回并稍后继续,那么睡眠可能会发生,但这基本上就是线程。
因此,你基本上坚持了别人的建议——你需要将代码分解为多个函数。
那么,你的问题有点错误。没有办法按照你想要的方式睡觉,你也不应该追求你建议的解决方案。
在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!
});