2012-06-16 35 views
3

目前,我使用的setInterval运行调用PHP页面,像这样几个AJAX功能 -替代的setInterval是等待函数来完成

var intervalOne = setInterval(ajaxfunction, 1500); 

能正常工作在测试服务器上有微小的响应时间。然而,偶尔在我的实时服务器上,会有一点滞后,间隔时间会在第一个完成之前再次出现,重复相同的调用并导致重复的数据出现。

有没有办法保持相同的间隔时间,但是如果第一个还没有完成,是否有等待调用该函数?

另外,有什么我可以放在AJAX调用的readystate部分,让他们一旦完成后再次触发自己?

编辑 - 我的Ajax调用一个实例:

function Send() { 
var name = document.getElementById('name').value; 
var message = document.getElementById('message').value; 

var xmlhttp = getXMLHttp(); 

xmlhttp.onreadystatechange = function() { 
    if(xmlhttp.readyState == 4) 
    { 
     document.getElementById('message').value = ""; 

     if(xmlhttp.responseText != "") { 
      var chat = document.getElementById('messagebox'); 
      chat.innerHTML = chat.innerHTML + '<div class=\"alert\">' + xmlhttp.responseText + '</div>'; 
      chat.scrollTop = 1000000000; 
     } 
    } 
} 

xmlhttp.open("POST","submit_message.php",true); 
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
xmlhttp.send("name=" + name + "&message=" + message); 

} 
+2

只需在函数结尾调用setTimeout? –

+0

显示您的AJAX呼叫,以便我们提供更好的答案。 –

+0

@James我真的可以自己调用一个函数吗? – Morgan

回答

6

最简单的方法是通过在你的进程结束盲目重新应用setTimeout

function foo() { 
    // possibly long task 
    setTimeout(foo, 1500); 
} 
foo(); 

这将等待你的进程之间的1500毫秒。就像这样:300ms的过程中,1500毫秒等待,2000点毫秒过程中,1500毫秒等待,400ms的过程中,1500毫秒稍候...

有点更接近于你想要什么,你可以重新申请setTimeout开始你的过程。在这种情况下,你会得到:300ms进程,1200ms等待,2000ms进程,0ms等待,400ms进程,1100ms等待... setInterval发生的问题在这里不会发生,因为这只会计划下一个迭代,不是所有未来的。还要注意,由于JS是单线程的,所以事件不能像其他语言中那样中断自身。

function foo() { 
    setTimeout(foo, 1500); 
    // possibly long task 
} 
foo(); 

,是的,我想这是更受追捧,使其自动执行的,因为你可以在一些答案看;但这只是美学,最终效果是一样的。

+0

谢谢,那正是我需要的。我没有意识到我可以设置参数来影响函数本身声明中函数的迭代。 – Morgan

+0

当一个完成时,摩根总是做另一个Ajax请求,所以试试@ TomaszNurkiewicz的回答 – 2012-06-16 12:45:52

2

您可以创建setTimeout这样沿着自我调用函数:

(function foo(){ 

// your code logic here 

setTimeout(foo, 5000); 

})(); 

这里的区别是,它的工作类似到setInterval但与其不同,只有在your code logic here部分执行完毕后才会执行下一个函数调用。

查看DEMO这里。

3

您可以替换setInterval()setTimeout()每个Ajax响应不断被重新安排:

function Send() { 
    //... 
    xmlhttp.onreadystatechange = function() { 
     if(xmlhttp.readyState == 4) { 
      setTimeout(Send, 1500); 
      //... 
     } 
    } 
} 

Send(); 

如果你并不需要精确到毫秒,这是好的(电话之间的时间将是1500毫秒+平均响应时间)。如果您需要每1500毫秒调用一次服务器,则可以从1500毫秒中减去响应时间。

+0

最好的答案,但它没有在jquery下标记 – 2012-06-16 12:08:52

+0

这是一个有用的答案,但我不希望为一个单一任务添加jQuery。 :) – Morgan

+0

@Somebodyisintrouble:[tag:jquery]仅用于强调这个想法,但是由于OP公布了原始代码,所以使用原始XMLHttpRequest代替。 –