有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。
如果您想要在所有浏览器上都可用的代码,请使用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秒钟!”);}
我有这个问题很久了,我需要的答案并不完全是这里提供的。此等待函数会导致同步等待,而不会占用CPU。
函数waitForIt向任何地方发出Ajax请求,并将异步标志设置为false。函数waitF对一个帧执行相同的操作,函数waitD对一个div执行相同的处理。Ajax大约需要100毫秒,frame大约是25,div大约是1。
wait函数根据您给它的时间来利用所有这些。如果它等待的时间不够长,请再次执行。
在处理多个异步加载元素时,我需要这个。基本上是“等待此元素存在”。你可以在https://jsfiddle.net/h2vm29ue/.它只是利用了浏览器自然等待的东西。较长的版本,https://jsfiddle.net/5cov1p0z/32/,更精确。
function waitForIt() {
var start = new Date();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Doesn't matter
}
};
xhttp.open("GET", "WaitForIt", false);
xhttp.send();
var end = new Date();
}
//
function waitF() {
var start = new Date();
var ifram = document.createElement('iframe');
ifram.id = 'ifram';
ifram.src = '';
var div = document.createElement('div');
div.id = 'timer';
document.body.appendChild(div);
document.getElementById('timer').appendChild(ifram);
document.getElementById('timer').removeChild(ifram);
document.body.removeChild(div);
var end = new Date();
return (end - start);
}
function waitD() {
var start = new Date();
var div = document.createElement('div');
div.id = 'timer';
document.body.appendChild(div);
div.click();
document.body.removeChild(div);
var end = new Date();
return (end - start);
}
function wait(time) {
var start = new Date();
var end = new Date();
while ((end - start < time)) {
if ((time - (end - start)) >= 200) {
waitForIt();
} else {
if ((time - (end - start)) >= 50) {
waitF();
} else {
waitD();
}
}
end = new Date();
}
return (end - start);
}
首先,应该使用setTimeout和setInterval,因为JavaScript具有回调性质。如果您想使用sleep(),则是控制流或代码架构不正确。
尽管如此,我想我仍然可以帮助实现两个睡眠。
1.我头顶上的假同步跑步:
// A module to do that //dual-license: MIT or WTF [you can use it anyhow and leave my nickname in a comment if you want to]
var _ = (function(){
var queue = [];
var play = function(){
var go = queue.shift();
if(go) {
if(go.a) {
go.f();
play();
}
else
{
setTimeout(play, go.t);
}
}
}
return {
go:function(f){
queue.push({a:1, f:f});
},
sleep:function(t){
queue.push({a:0, t:t});
},
playback:play
}
})();
[也可以自动播放]
// Usage
_.go(function(){
// Your code
console.log('first');
});
_.sleep(5000);
_.go(function(){
// Your code
console.log('next');
});
// This triggers the simulation
_.playback();
2.实际同步运行
有一天,我对它进行了很多思考,我在JavaScript中真正睡觉的唯一想法就是技术。
睡眠函数必须是同步Ajax调用,超时设置为睡眠值。这就是真正睡觉的唯一方法。
如果你写一个这样的睡眠函数
var sleep = function(period, decision, callback){
var interval = setInterval(function(){
if (decision()) {
interval = clearInterval(interval);
callback();
}
}, period);
}
你有一个异步函数可以多次调用,
var xhr = function(url, callback){
// Make an Ajax request
// Call a callback when the request fulfils
}
您的项目设置如下:
var ready = false;
function xhr1(){
xhr(url1, function(){ ready = true;});
}
function xhr2(){
xhr(url2, function(){ ready = true; });
}
function xhr3(){
xhr(url3, function(){ ready = true; });
}
然后您可以执行以下操作:
xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
// Do more
});
而不是像这样无休止的回调缩进:
xhr(url1, function(){
xhr2(url2, function(){
xhr3(url3, function(){
// Do more
});
});
});
我同意其他海报。忙着睡觉是个坏主意。
但是,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,以执行它排队的任何其他代码。
正如评论中指出的那样,这绝对不会在循环中工作。你可以做一些花哨的(丑陋的)黑客来让它在一个循环中工作,但总的来说,这只会导致灾难性的意大利面条代码。