setInterval in jQuery happens too fast
I use setInterval and sometimes it happens "too fast". Here how it looks:
setInterval(function() {
开发者_如何学Go //here comes ajax functions and so on.
}, 1000);
Sometimes setInterval happens faster than all those ajax functions and it gives me two messages instead of one. What a solution to this?
It's hard to tell what you're running into, the question is a bit unclear.
setInterval
is great for some things, but not for anything where you're going to be mixing other asynchronous stuff in with it. Instead, use the "rescheduling setTimeout
" idiom:
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);
}
});
}
...because, after all, your ajax
call may take more than a second to complete.
If that's not the problem you're having, my guess is your code looks something like this:
setInterval(function() {
$.ajax("your_url", {
success: function() {
// Do something here
}
});
// Do something else here
}, 1000);
...and you're wondering why the "Do something else here" code is running before the "Do something here" code. If so, the reason is that by default, ajax calls are asynchronous. Your call to $.ajax
starts the call, but that's all; then all your other code runs before the success (or error) callbacks occur.
The fix, of course, is to not do anything else at the top level that relies on the success callback:
setInterval(function() {
$.ajax("your_url", {
success: function() {
// Do something here
// Do something else here
}
});
}, 1000);
With jQuery 1.5.x you can use the Then() for deferred object. This is a nice way to say once you are done then() do this. You can also use the When() option to have it wait for more than one ajax request to complete.
These two things are very cool and powerful.
http://api.jquery.com/deferred.then/
http://api.jquery.com/jQuery.when/
Set a flag that indicates that the ajax fetches are in process. When all of the ajax fetches complete, clear the flag. At the top of your setInterval
function, return immediately if the flag is set.
It's better not to use setInterval
, but to set a fresh setTimeout
each time. For example:
setTimeout(function ajaxStuff() {
// here comes ajax functions and so on.
setTimeout(ajaxStuff, 1000);
}, 1000);
Of course, if the functions within are asynchronous, as AJAX requests normally are, the setTimeout
call will still come too soon. You'll need to write some code that calls setTimeout
when the requests are complete. $.when
helps you with this, since $.ajax
and other jQuery AJAX methods implement $.Deferred
:
setTimeout(function ajaxStuff() {
$.when(
$.ajax({
url: 'ajax1.htm'
}),
$.ajax({
url: 'ajax2.htm'
}),
$.ajax({
url: 'ajax3.htm'
})
).done(function() {
setTimeout(ajaxStuff, 1000);
});
}, 1000);
I think the problem here is due to scope. Eventhough the method is triggered successfully.
With similar problem I have able to use this to fix:
setTimeout(function(){
load1();
}, 5000);
function load1 () {
console.log('loaddd1..');
setTimeout(load2(), 4000);
}
function load2 () {
setTimeout(function(){
console.log('end load2');
}, 4000);
had this issue and clearInterval wasn't working.
make sure setInterval is only called once by wrapping it in an if statement:
var interval;
if (typeof(interval) === 'undefined') {
interval = setInterval(actFakeData,3000);
}
also helpful for me was assigning setInterval to a variable and console.log it so you can see the value throughout your code. for me when it was speeding up it was increasing in numeric value instead of resetting until I wrapped it in this.
精彩评论