问题
Having problems with some intervals here.
The basic concpt is that i have a progress bar function, 1 per row of things, being fed info from a back end script. I ping this script every 5 seconds within an interval to an ajax call.
This works, however there are problems with multiples (ie, a 2nd progress bar calls the same function) or when the item is 'closed' (a div slide) it should stop. This is some very inter-trined code, so i'll try my best to pull out the necessary parts, but note that as it stands, this likely won't run.
a complete walk though- function names have been changed to protect the innocent :)
onlcick, div opens, and this start function is called:
function start(ID){
var request = $.ajax({
url: "script?DO=Start&ID="+ID
, type: "GET"
, cache: false
, dataType: "text"
});
request.done(function(msg) {
startLoop(ID);
});
request.fail(function(jqXHR, textStatus) {
//alert("Request failed: " + textStatus );
});
}
as you can see, this calls the startLoop fnc, which continues to ping the update info script (getInfo()) for info:
function startLoop(ID){
var i = setInterval(function(){
var xstatus = getInfo(ID);
//other stufff that works
if(xstatus=="done"){
clearInterval(i);
}
}, 5000);
}
This in and of it self works fine.
If a 2nd click event opens a 2nd window, it simply has a new ID and calls the same functions.
Thus, I have one i interval, and destroying one seems to stop everything. Should i convert i to be an object, like i.ID ?
Also, when stopped, I have an onclick =stop() call, and from outside the loop, I can't seem to stop it.
How do i re-arrange this to make it work?
it should support start, stop, and autoupdating, for 1 or many simultaneous items.
回答1:
Why not use setTimeout
instead of clearInterval
, since you're already putting the responsibility of killing the interval inside its callback:
// using this approach might require changing the name of this function
function startLoop(ID) {
setTimeout(function(){
var xstatus = getInfo(ID);
//other stufff that works
if(xstatus!=="done"){
startLoop(ID); // do it all over again if it's not complete
}
}, 5000);
}
This will give you the same behavior, but with a couple of added bonuses. For one, this shouldn't result in your other jobs being killed when one is complete. The other is that this will run asynchronously, so if the requests start taking more than 5 seconds to complete, the timeout won't ping it again for 5 seconds after it returns, as opposed to blindly firing every 5 seconds, whether or not the request has been completed.
来源:https://stackoverflow.com/questions/14987941/clearinterval-and-scope