clearInterval fails in one scenario but not the other
-
25-06-2021 - |
Question
I'm running a function to check if a database entry exists.
On my page load I check if an element exists and if it does I use setInterval
to run a function. Like so:
if ( $('#encoding').length ) {
console.log("auto_update start");
var update = setInterval(auto_update, 12000);
}
Then in my auto_update
function this happens
function auto_update() {
console.log("auto_update running");
$.ajax({
type: 'POST',
url: ajaxurl,
data: {
action: "dhf_ajax_router",
perform: "dhf_check_status", // the function we want to call
post_id: $('#post_id').val(),
nonce: $('#dhf-video-meta-nonce').val()
},
success: function(response) {
if ( response === "continue" ) {
console.log("still encoding");
} else {
clearInterval(update);
console.log("complete " + response);
}
}
});
}
The problem is if $('#encoding')
wasn't present on the page at the start and was fired by the user manually within:
$(document).on("click", ".run_encode", function(){
// doing the necessary stuff here.
if ( response === "sent" ) {
// more stuff
var update = setInterval(auto_update, 12000);
}
}); // end .run_encode
Then the clearInterval(update)
doesn't work, and it ends up in an endless loop.
I can't figure out Why. An interval with the name update
was set in both cases, so why does clearing it not work in the second situation?
Solution
You will have to make sure that the shared variable update
is available in both scopes. This means that it either needs to be in a common parent scope or you need to make the update
variable a global variable so it does not go out of scope.
Most likely, you're declaration of update
is inside a function that terminates and when that function terminates, the update
variable goes out of scope and is destroyed.
You can make the initial setting of the variable go into the global scope (so it will still be available when you call clearInterval()
like this:
$(document).on("click", ".run_encode", function(){
// doing the necessary stuff here.
if ( response === "sent" ) {
// more stuff
window.update = setInterval(auto_update, 12000);
}
}); // end .run_encode
Or, you could just declare the update
variable to be global, by first putting this at the global level (outside of any functions) and then this code would just modify the global variable:
var update;
$(document).on("click", ".run_encode", function(){
// doing the necessary stuff here.
if ( response === "sent" ) {
// more stuff
update = setInterval(auto_update, 12000);
}
}); // end .run_encode
OTHER TIPS
You declare the update
variable inside a function. The other function can't access it's value.
jfriend00 gave an extensive answer on how to solve it. I'd take another route: use setTimeout
. This is recommended anyway, because the AJAX call does not take a constant time but varies every time. Imagine it takes over 12 seconds due to network trouble: you'll be screwed.