2011-08-03 61 views
14

我有一段代码,需要执行一段时间后才能执行,例如5000 ms.Currently我正在使用setTimeout,但它是异步的,我希望执行等待它的返回。我曾尝试使用以下尝试:代码执行中的同步延迟

function pauseComp(ms) 
{ 
    var curr = new Date().getTime(); 
    ms += curr; 
    while (curr < ms) { 
     curr = new Date().getTime(); 
    } 
} 

但我不想耽误正在起草使用raphaeljs一些对象的代码和显示一点也不顺利。我正在尝试使用doTimeout插件。由于要延迟的延迟和代码都处于循环状态,因此我只需要延迟一次。我没有要求的ID,所以我没有使用它。 例如:

for(i; i<5; i++){ $.doTimeout(5000,function(){ 
     alert('hi'); return false;}, true);} 

此等待5秒befor给第一Hi和然后连续循环迭代之后紧接在第一显示警告。我想要它做的是等待5秒,再次发出警报等待,然后给予警报等。

任何提示/建议表示赞赏!

回答

2

JavaScript是一种单线程语言。您不能合并setTimeout和同步处理。会发生什么事,定时器会失效,但是然后JS引擎会等待处理结果,直到当前脚本完成。

如果你想要同步方法,直接调用方法!

如果您想在setTimeout之后处理某些内容,请将其包含或从超时函数中调用它。

3

非超时循环(检查时间或计数到1000000或其他)只会锁定浏览器。 setTimeout(或$.doTimeout插件)是最好的方法。

在循环中创建超时将不起作用,因为在继续之前,循环不会等待先前的超时发生,正如您发现的那样。尝试更多的东西是这样的:

// Generic function to execute a callback a given number 
// of times with a given delay between each execution 
function timeoutLoop(fn, reps, delay) { 
    if (reps > 0) 
    setTimeout(function() { 
       fn(); 
       timeoutLoop(fn, reps-1, delay); 
       }, delay); 
} 

// pass your function as callback 
timeoutLoop(function() { alert("Hi"); }, 
      5, 
      5000); 

(我只是拼凑这个快起来,使其作品,虽然我相信它可以在几个方面,如待提高,“循环”中它可以通过一个指数值放到回调函数中,这样你自己的代码就可以知道它要做什么迭代了,但希望它能帮助你开始。)

+0

旁边的setTimeout是一个更好的选择,在OP请求syncronous方法@ThinkBonobo回答正确 – robsonrosa

+1

@robsonrosa - 的OP也说:”我不想耽误代码是画些使用raphaeljs和显示的对象并不是一帆风顺的“,你不能使用同步代码*和*绘制东西,因为在同步代码完成之前,屏幕不会被重新绘制,因为OP要求的东西不会让它成为可能 – nnnnnn

20

对接受的答案的变化与此一样好。

而且,我同意宁愿setTimeout和异步函数调用,但有时如构造测试时,你只需要一个同步等待命令的注意事项...

function wait(ms) { 
    var start = Date.now(), 
     now = start; 
    while (now - start < ms) { 
     now = Date.now(); 
    } 
} 

如果你想让它在几秒钟内,在开始毫秒的同时检查...

+2

它应该是被接受的答案 – robsonrosa

0

我做了一个简单的同步超时功能。它有两种不同的方式,回调和非回调。

功能:

function wait(ms, cb) { 
    var waitDateOne = new Date(); 
    while ((new Date()) - waitDateOne <= ms) { 
    //Nothing 
    } 
    if (cb) { 
    eval(cb); 
    } 
} 

回调例如:

wait(5000,"doSomething();"); 

非回调例如:

console.log("Instant!"); 
wait(5000); 
console.log("5 second delay"); 
+1

使用'cb()'而不是'eval(db)'。脚本中的字符串不是一个好习惯。用法:'wait(5000,function(){console.log(“test!”)})'。顺便说一句,如果你需要回调,最好使用setTimeout – Soaku

0

这里是你如何使用JQuery的doTimeout插件

jQuery('selector').doTimeout([ id, ] delay, callback [, arg ... ]); 

docs:“如果回调返回true,则doTimeout循环将再次执行,延迟后,创建一个轮询循环,直到回调返回一个非真正的价值。

var start = Date.now(); 
 
console.log("start: ", Date.now() - start); 
 
var i = 0; 
 
$.doTimeout('myLoop', 5000, function() { 
 
    console.log(i+1, Date.now() - start); 
 
    ++i; 
 
    return i == 5 ? false : true; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-dotimeout/1.0/jquery.ba-dotimeout.min.js"></script>