2011-04-15 77 views
2

我使用setInterval,有时它发生“太快”。它下面的样子:jQuery中的setInterval发生得太快

setInterval(function() { 
    //here comes ajax functions and so on. 
}, 1000); 

有时会发生的setInterval比所有这些AJAX功能,速度更快,它给了我两个消息,而不是一个。这是什么解决方案?

+1

也许你不应该使用的setInterval可言。您可能想要触发这些呼叫,然后使用setTimeout在呼叫回来后再次安排呼叫。 – mahemoff 2011-04-15 21:09:59

回答

10

很难说出你遇到的问题,这个问题有点不清楚。

setInterval对于某些事情很有用,但不适用于任何需要混合其他异步内容的任何事情。相反,使用“重新安排setTimeout”成语:

setTimeout(doSomething, 1000); 
function doSomething() { 
    $.ajax("your_url", { 
     success: function() { 
      // Do something here 

      // Do something else here 
     }, 
     complete: function() { 
      // Previous run complete, schedule the next run 
      setTimeout(doSomething, 1000); 
     } 
    }); 
} 

...因为,毕竟,你ajax通话可能需要超过一秒钟来完成。

如果这不是你所遇到的问题,我的猜测是你的代码看起来是这样的:

setInterval(function() { 
    $.ajax("your_url", { 
     success: function() { 
      // Do something here 
     } 
    }); 

    // Do something else here 
}, 1000); 

...你想知道为什么“人在这里做什么”代码运行在“在这里做某事”代码之前。如果是这样,原因是默认情况下,ajax调用是异步。你的电话$.ajax开始的呼叫,但这就是全部;那么在成功(或错误)回调发生之前,所有其他代码都会运行。

的修复,当然,是在依赖于成功的回调顶级不做任何其他

setInterval(function() { 
    $.ajax("your_url", { 
     success: function() { 
      // Do something here 

      // Do something else here 
     } 
    }); 

}, 1000); 
1

最好不要使用setInterval,而是每次都设置一个新的setTimeout。例如:

setTimeout(function ajaxStuff() { 
    // here comes ajax functions and so on. 

    setTimeout(ajaxStuff, 1000); 
}, 1000); 

当然,如果内部的函数是异步的,因为AJAX请求通常是,在setTimeout呼叫仍将会来得太早。您需要编写一些在请求完成时调用setTimeout的代码。 $.when可以帮助您与此,因为$.ajax和其他的jQuery AJAX方法来实现$.Deferred

setTimeout(function ajaxStuff() { 
    $.when(
     $.ajax({ 
      url: 'ajax1.htm' 
     }), 
     $.ajax({ 
      url: 'ajax2.htm' 
     }), 
     $.ajax({ 
      url: 'ajax3.htm' 
     }) 
    ).done(function() { 
     setTimeout(ajaxStuff, 1000); 
    }); 
}, 1000); 
+0

这是否只是排队XHR请求,然后立即设置下一个超时,这可能会导致相同的行为? – 2011-04-15 21:07:43

+0

@Jason是的。为了解决这个问题,我编辑了一半。 – lonesomeday 2011-04-15 21:08:54

1

设置一个标志,指示阿贾克斯取的过程中。当所有ajax提取完成后,清除标志。在setInterval函数的顶部,如果标志被设置,立即返回。

1

我觉得这里的问题是由于范围。尽管该方法已成功触发。

类似的问题我已经能够使用该修复:

setTimeout(function(){ 
    load1(); 
}, 5000); 

function load1() { 
    console.log('loaddd1..'); 
    setTimeout(load2(), 4000); 
} 

function load2() { 
    setTimeout(function(){ 
    console.log('end load2'); 
}, 4000);