Try with: clearTimeout() in else condition .
You need to create the setTimeout() in one variable.Then apply the clearTimout() if the condition is false(Its means a else statement)
var timer;
//call effect on load
$(function() {
moveSlide(true);
});
//move the div
function moveSlide(repeat) {
if(repeat === true) {
console.log('running')
$('#slide_show').slideToggle('slow',function() {
timer = setTimeout(function() {
moveSlide(true);
},2000);
});
} else {
clearTimeout(timer);
console.log('stopped')
return;
}
}
//stop the function
$(document).on('click','.stop',function(e) {
e.preventDefault();
moveSlide(false);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div id="slide_show"></div>
<a href="#" class="stop">Stop</a>
Answer from prasanth on Stack OverflowTry with: clearTimeout() in else condition .
You need to create the setTimeout() in one variable.Then apply the clearTimout() if the condition is false(Its means a else statement)
var timer;
//call effect on load
$(function() {
moveSlide(true);
});
//move the div
function moveSlide(repeat) {
if(repeat === true) {
console.log('running')
$('#slide_show').slideToggle('slow',function() {
timer = setTimeout(function() {
moveSlide(true);
},2000);
});
} else {
clearTimeout(timer);
console.log('stopped')
return;
}
}
//stop the function
$(document).on('click','.stop',function(e) {
e.preventDefault();
moveSlide(false);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div id="slide_show"></div>
<a href="#" class="stop">Stop</a>
I see that you are calling ever time at the method moveSlide, into the setTimeout
$('#slide_show').slideToggle('slow',function() {
setTimeout(function() {
**///moveSlide(true); ///here , will be calling recursive untill end**
},2000);
});
Test and tell us, if will help it
tks
I wanted to get some practice working with Date.now and the date object within JS so I started working on a stop watch.
The problem I am having is with a recursive function I used to update the time. It seems the issue is related to the recursive function continuing to run updateTime() indefinitely, even when the state of the clock has been set to paused.
Codpen: https://codepen.io/bluehabit/pen/PKVQMq
if(startTime){
setTimeout(function(){
difference = timeDifference(baseTime, endTime);
convertedDifference = convertTime(difference);
var seconds = convertedDifference.seconds;
var minutes = convertedDifference.minutes;
var milliseconds = convertedDifference.milliseconds;
console.log(convertedDifference);
printTimeResult(convertedDifference)
updateTime();
}, 3);
} else {
return;
}When I pause the timer the recursive function continues to run in the background updating the time.
For example if you were to start the timer, pause it at 5 seconds and were to wait an additional 5 seconds. The function continues to run in the background and the time would be 10 seconds instead of 5 where you left off when you resume the timer.
Here is an example of this issue:
http://imgur.com/66HJfdt
You might want to use setInterval() instead of setTimeout() to make it simpler.
To start the timer, make sure baseTime and endTime are initialized or have the valid values, then use below example code.
timerId = setInterval(yourFunction, 3);
When you need to pause the timer, use below code.
clearInterval(timerId);
You issue does not lie in the updateTime continuing to run, but in a way you calculate time difference inside of it: you are not counting time while your timer was running, you are counting time since timer was first started — you set baseTime when user first clicks "Start" button after loading the page (when timeWarp.startCounter is false), and then calculate difference between that and current time in the setTimeouted function.
You would need to either reset timeWarp.startCounter back to false if you want to completely reset timer on "Stop" click, or introduce some variable that would hold amout of time passed and add time to it while counter is in the running state (i.e. when startTime is true).
Does it make sense?
jquery - How to Stop a Recursive Function in JavaScript? - Stack Overflow
Break out of Javascript recursive function on .click()
jquery - How to externally pause and stop recursive javascript function - Stack Overflow
javascript - How to stop function recursion - Stack Overflow
Videos
Try
function findCategory(categoryName) {
var trail = [];
var found = false;
function recurse(categoryAry) {
for (var i = 0; i < categoryAry.length; i++) {
trail.push(categoryAry[i].category);
// Found the category!
if ((categoryAry[i].category === categoryName)) {
found = true;
break;
// Did not match...
} else {
// Are there children / sub-categories? YES
if (categoryAry[i].children.length > 0) {
recurse(categoryAry[i].children);
if(found){
break;
}
}
}
trail.pop();
}
}
recurse(catalog);
return trail
}
Demo: Fiddle
the return stmt does work but remember it will be called everytime the loop unwinds and that's not what you are looking at. Example
// global scope
String matchingVariable;
int getMatch(index count, String input, String[] inputs){
if(isValid(input) || count < inputs.length){
// your condition is met and break
// assign your value to global scope variable
matchingVariable = input;
}else if(matchingVariable ==null){
++count
if(count < inputs.length){
getMatch(count, input+inputs[count], inputs)
}
// NOTE RETURN - I WOULDN'T DO THIS
return input;
// doesn't work instead assign the input to global scope variable when a match is found.
}
}
You can easily solve this with state. Simply add a variable to your code called
var isRunning = false;
which it to true when you start the animation, and false to stop the animation. Then inside your iterator function, check to see if isRunning is false. If isRunning === false, you don't call the next setTimeout, hence stopping the animation.
I'd probably use setInterval/clearInterval outside your interval function. You definitely want recurring intervals instead of single timeouts when you think about it.
So basically:
var something;
function start() {
something = setInterval(interval, 1000);
}
function interval() {
//animation code
}
function stop() {
clearInterval(something);
}
Something like:
var needStop = false;
function create_abcd()
{
var dataString = 'action=create_abcd&type=' + $('#abcd_type').val() + '&count=100';
$.ajax({
type: "POST",
url: "backend.php",
data: dataString,
success: function(msg){
if(needStop) {
needStop = false;
return;
}
if(msg != "0")
{
$("#abcd_output").append('<p>' + msg + '</p>')
setTimeout(create_abcd, 2000);
}
else
return false;
}
});
}
$('#button').click(function() {
needStop = true;
});
=)
I think you're trying to solve your problem in a wrong way. You're obviously want to gen notified when some long-running process finishes on the server, so you poll every 2 secs. This will cause a lot of unnecessary requests.
Instead use push mechanism.
Consider using COMET, since you're PHP:
http://www.zeitoun.net/articles/comet_and_php/start
Since you already have returns in the code I'm assuming you know that you can just return from the function at that point.
You could return with a value that means something somewhere else.
The functionality that you want is almost (or is) a goto.
So, since exceptions run very similarly to gotos you could implement the method something like the following by throwing an exception when the thing occurs.
function generateParseTree(parsingArray, left, right, rootIndex) {
try
{
probability *= parsingArray[left][right][rootIndex].prob;
if (!parsingArray[left][right][rootIndex]['divide']) {
if (left == parsingArray.length - 2 && right == parsingArray.length - 1) {
if (probability > 1e-6) {
suming ++;
throw "this thing is done";
}
return;
} else {
return;
}
}
generateParseTree(parsingArray, left, parsingArray[left][right][rootIndex]['divide'], parsingArray[left][right][rootIndex]['right1Index']);
generateParseTree(parsingArray, parsingArray[left][right][rootIndex]['divide'], right, parsingArray[left][right][rootIndex]['right2Index']);
return;
}
catch (err)
{
console.log(err); // "this thing is done"
}
}
can't you just return from the place you'd place break?
I want to stop this function but I'm not sure how, I'm using React. I can't use a while(boolean) because I'd have to wait until all the code inside the function is done in order for the function to stop. My solution was to add an if statement for every step of the function and a setInterval inside the resolveAfter, but it's a really messy solution but I think it could work. Is there any better way to deal with this problem?
const resolveAfter = (delay: number) =>
new Promise<void>((resolve) => {
setTimeout(() => resolve(), delay * 1000);
});
async function startPomodoro(timers: PomodoroTimers) {
const ringToneDuration = ringtoneRef.current?.duration
? ringtoneRef?.current?.duration
: 0;
// POMODORO
if (!isFirstTime) {
await playAlarm(ringToneDuration);
}
console.log(`Pomodoro Started, wait ${timers.pomodoro}s`);
setIsPomodoroRunning(true);
console.log(isPomodoroRunning);
setFinishTime(timers.pomodoro);
await resolveAfter(timers.pomodoro);
// RINGTONE
console.log(`Ringtone Started, wait ${timers.break}s`);
await playAlarm(ringToneDuration);
// BREAK
console.log(`Break Started, wait ${timers.break}s`);
setFinishTime(timers.break);
await resolveAfter(timers.break);
isFirstTime = false;
startPomodoro(timers);
}Using recursion to implement a slideshow is probably not a good idea because it will eventually give a stack overflow.
Use timeouts instead.
setTimeout() - executes a code some time in the future
clearTimeout() - cancels the setTimeout()
Or intervals (thanks Ricket for pointing this out!):
The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds).
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
instead of indirect recursion, try using a recurring timeout (var timer_id = setInterval(...)) and use clearTimeout when you want to stop it
Here this will stop the animate function after two seconds. I have marked the changes I made with the comment '//new change'. You can control the time in milliseconds the animation runs using the setTimeOut function. I have used 2 seconds for example. You can also set this using a random generator to get different time spans.
var animate = false; //new change
$(function () {
$('.a').mouseenter(function() {
animate = true;//new change
animateDiv();
setTimeout(function(){animate = false },2000)//new change
});
});
function makeNewPosition() {
var h = $(window).height() - 50;
var w = $(window).width() - 50;
var nh = Math.floor(Math.random() * h);
var nw = Math.floor(Math.random() * w);
return [nh, nw];
}
function animateDiv() {
var newq = makeNewPosition();
console.log(newq);
$('.a').animate(
{top: newq[0],
left: newq[1], }
,400, function () {
if(animate) animateDiv();//new change
});
};
Here is a jsfiddle. Check the console log
Here is how this works. Before you begin animation in recursive function you set animation flag to true. The function calls itself only if this flag is true. Then you start a saperate timer which make animate flag false, which will cause the recursive function to break.
PS: The animation code in your original question doesn't work anyway. But i didn't try to debug it as your question was only about how to stop the function after a while.
You could do a setTimeout to stop it.
setTimeout(function (){
$('.a').stop();
}, "1000");
This will stop any animations present on any element with the class a after 1 second.