有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。
可以使用带有递增较大值的闭包调用setTimeout()。
var items = ['item1', 'item2', 'item3'];
function functionToExecute(item) {
console.log('function executed for item: ' + item);
}
$.each(items, function (index, item) {
var timeoutValue = index * 2000;
setTimeout(function() {
console.log('waited ' + timeoutValue + ' milliseconds');
functionToExecute(item);
}, timeoutValue);
});
结果:
waited 0 milliseconds
function executed for item: item1
waited 2000 milliseconds
function executed for item: item2
waited 4000 milliseconds
function executed for item: item3
我同意其他海报。忙着睡觉是个坏主意。
但是,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,以执行它排队的任何其他代码。
正如评论中指出的那样,这绝对不会在循环中工作。你可以做一些花哨的(丑陋的)黑客来让它在一个循环中工作,但总的来说,这只会导致灾难性的意大利面条代码。
这里的大多数答案都是错误的,或者至少是过时的。没有理由JavaScript必须是单线程的,事实上也不是。今天,所有主流浏览器都支持工人。在此之前,Rhino和Node.js等其他JavaScript运行时支持多线程。
“JavaScript是单线程的”不是有效答案。例如,在工作线程中运行睡眠函数不会阻止UI线程中运行的任何代码。
在支持生成器和yield的较新运行时中,可以在单线程环境中为sleep函数带来类似的功能:
// This is based on the latest ES6 drafts.
// JavaScript 1.7+ (SpiderMonkey/Firefox 2+) syntax is slightly different
// Run code you want to sleep here (omit star if using JavaScript 1.7)
function* main(){
for (var i = 0; i < 10; i++) {
// To sleep for 10 milliseconds 10 times in a row
yield 10;
}
yield 5;
console.log('I just slept 5 milliseconds!');
}
// Resume the given generator after ms milliseconds
function resume(ms, generator){
setTimeout(function(){
// Omit .value if using JavaScript 1.7
var nextSleep = generator.next().value;
resume(nextSleep, generator);
}, ms);
}
// Initialize a generator and get first sleep for the recursive function
var
generator = main(),
firstSleep = generator.next().value;
// Initialize recursive resume function
resume(firstSleep, generator);
这种对睡眠的模仿不同于真正的睡眠函数,因为它不会阻塞线程。它只是JavaScript当前setTimeout函数之上的糖。这种功能类型已经在Task.js中实现,现在应该可以在Firefox中使用。