Stop recursive setTimeout function - javascript

Im running a recursive setTimeout function and I can run it many times, it has a clearTimeout, with this property I can handle how to stop the function running.
But I can't figure out how to stop it in another function.
var a = 0;
var b = 0;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
setTimeout(Listener.bind(this, x, y), 1000);
} else {
clearTimeout(Listener);
if(y == true){
a=0;
}else{
b=0;
}
}
}
When i tried to run it twice, it works:
My doubt is: How can I stop a particular running instance.

A couple notes:
Given the constant timeout of 1000, you should be using setInterval() instead. It will greatly simplify your function, and allow you to cancel the interval whenever you want.
Using global variables is code smell, create an object instead to hold a reference to the value being incremented. Doing so will also allow your function parameters to be more intuitive.
Here's a solution incorporating these two suggestions:
function range (step, start = 0, stop = 100) {
const state = {
value: start,
interval: setInterval(callback, 1000)
};
function callback () {
if (state.value < stop) {
console.log(state.value);
state.value += step;
} else {
console.log('timer done');
clearInterval(state.interval);
}
}
callback();
return state;
}
const timer1 = range(10);
const timer2 = range(20);
setTimeout(() => {
console.log('stopping timer 1');
clearInterval(timer1.interval);
}, 2500);
setTimeout(() => {
console.log('timer 2 value:', timer2.value);
}, 3500);

You could elevate the timer to a higher scope that is accessible by other functions.
var a = 0;
var b = 0;
var timer = null;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if (y == true) {
a += x;
} else {
b += x;
}
timer = setTimeout(Listener.bind(this, x, y), 1000);
} else {
clearTimeout(timer);
if (y == true) {
a = 0;
} else {
b = 0;
}
}
}
function clearTimer() {
if (timer !== null) clearTimeout(timer);
}
Listener(3, 3);
// clear the timer after 3 secnods
setTimeout(clearTimer, 3000);

create a variable and store the reference of setTimout on that variable, after that you just clearTimout with that variable reference
e.x
GLOBAL VARIABLE:
var k = setTimeout(() => { alert(1)}, 10000)
clearTimeout(k)
var a = 0;
var b = 0;
var recursiveFunctionTimeout = null;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
recursiveFunctionTimeout = setTimeout(Listener.bind(this, x, y), 10);
} else {
clearTimeout(recursiveFunctionTimeout);
if(y == true){
a=0;
}else{
b=0;
}
}
}
LOCAL VARIABLE:
var a = 0;
var b = 0;
function Listener(x, y) {
var lValue = y == true ? a : b;
var recursiveFunctionTimeout = null;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
recursiveFunctionTimeout = setTimeout(Listener.bind(this, x, y), 10);
} else {
clearTimeout(recursiveFunctionTimeout);
if(y == true){
a=0;
}else{
b=0;
}
}
}

Related

if statement of button found

My goal is, if a page contains the specified button, click it, and increase the amt_clicked by 1. When amt_clicked is greater than 15, wait for 60 seconds and reset amt_clicked. I have no idea how do this if statement. Example:
var amt_clicked = 0;
while (1) {
while (amt_clicked < 15) {
if (button found) { // this is where I am lost
iimPlay("TAG POS={{amt_clicked}} TYPE=BUTTON ATTR=TXT:Get");
amt_clicked++;
}
}
iimPlay("WAIT SECONDS=60");
amt_clicked = 0;
}
This will run 20 times per second, using the window.setInterval() function:
var amt_clicked = 0;
var amt_cooldown = 1200;
setInterval(function(){
if (amt_cooldown === 0)
amt_cooldown = 1200;
else if (amt_cooldown < 1200)
amt_cooldown -= 1;
else if (amt_clicked > 15) {
amt_clicked = 1;
amt_cooldown -= 1;
} else {
amt_clicked -= 1;
//Click
}, 50);
You can use combination of setInterval and setTimeout.
I have added comments to code for you to understand.
var amt_clicked = 0;
var setTimeoutInProcess = false;
//processing the interval click function
setInterval(() => {
checkButtonAgain();
}, 200);
function checkButtonAgain() {
var element = document.getElementById('iNeedtoBeClicked');
//if clicked 15 times then need to wait for 60 seconds
if (amt_clicked === 15) {
if (!setTimeoutInProcess) {
setTimeoutInProcess = true;
setTimeout(function() {
//resetting the amt-clicked
amt_clicked = 0;
setTimeoutInProcess = false;
}, 60000);
} else {
console.log('waiting');
}
} else if (typeof(element) != 'undefined' && element != null) {
//triggering click and increasing the amt_clicked
element.click();
amt_clicked++;
}
console.log(amt_clicked);
}
<button id="iNeedtoBeClicked">Click ME Button</button>

Math.pow returning 0 in calc

I'm making a calculator currently and I'm running into an issue with one of the functions, specifically x^y, it keeps returning 0 and not even seeming to run the setInterval at all, though it runs without the if function around it. fn is for which function its using which is x^y, and vi is just a tool in the calculator to distinguish which number you are changing as in reactant, or reactant2, reactants are the 2 numbers that are squared against each other in this case. (this is only the portion of the code with the problem)
function click15(){
if (reactant > 0) {
reactant = parseFloat(reactant);
}
if (reactant2 > 0) {
reactant2 = parseFloat(reactant2);
}
if (fn === 0) {
product = reactant / reactant2;
} else if (fn === 1) {
product = reactant * reactant2;
} else if (fn === 2) {
product = reactant - reactant2;
} else if (fn === 3) {
product = reactant + reactant2;
} else if (fn === 4) {
if (vi === 0) {
vi = 1;
var timer = setInterval(function(){
if (vi === 0) {
product = (Math.pow(reactant, reactant2));
clearInterval(timer);
}
}, 4);
}
}
reactant = product;
product = 0;
reactant2 = "0";
vir = 0;
vir2 = 0;
vi = 0;
di1 = 0;
di2 = 0;
fn = -1;
}

How to create a pause in recursion function loop

I'm new here so sorry if dublicate.
I'm trying to write a sudoku solver using backtracking method to make it pass all data dynamically into the document with its each recursion. When I tried to use setInterval() or setTimeout() it doesn't work the way I want it to work. What I need should be similar to this
Here's the code:
function backtrack(position) {
if (position === 81) {
return true;
}
if (sudokuArray[position] > 0) {
backtrack(position + 1);
} else {
for (var x = 1; x <= 9; x++) {
if (isValid(x, parseInt(position / 9), position % 9) === true) {
sudokuArray[position] = x;
//some code that invokes putSudokuArrayBack function with a small delay
//everytime backtrack function is invoked
if (backtrack(position + 1) === true) {
return true;
}
}
}
sudokuArray[position] = 0;
return false;
}
}
function putSudokuArrayBack() {
for (var i = 0; i <= 81; i++) {
var indexString = '#val-' + parseInt(i / 9) + '-' + i % 9;
$(indexString).val(sudokuArray[i]);
}
}
Any ideas(if it's even possible)? Thanks in advance!

How to go faster than a short setTimeout in javascript?

How to make a script repeat it self faster than a setTimeout allows but still not as fast as possible?
Check this demo for 2 examples.
(I post the demo code under also)
var x = 0;
var divEl = document.getElementById('counter');
var divEl2 = document.getElementById('counter2');
document.getElementById('gosettimeout').addEventListener('click', go, false);
document.getElementById('gotoofast').addEventListener('click', go2, false);
function go() {
x++;
divEl.innerHTML = x;
if (x > 100) {
return false;
}
setTimeout(function () {
go();
}, 0);
}
function go2() {
x++;
divEl2.innerHTML = x;
if (x > 100) {
return false;
}
go2();
}
var x = 0;
var divEl = document.getElementById('counter');
var divEl2 = document.getElementById('counter2');
document.getElementById('gosettimeout').addEventListener('click', go, false);
document.getElementById('gotoofast').addEventListener('click', go2, false);
function go() {
x++;
divEl.innerHTML = x;
if (x > 100) {
return false;
}
if (x % 2 == 0) {
setTimeout(function () {
go();
}, 0);
} else {
go();
}
}
function go2() {
x++;
divEl2.innerHTML = x;
if (x > 100) {
return false;
}
go2();
}
Two times faster, but not as fast as possible =)
var x = 0;
var divEl = document.getElementById('counter');
var divEl2 = document.getElementById('counter2');
document.getElementById('gosettimeout').addEventListener('click', go, false);
document.getElementById('gotoofast').addEventListener('click', go2, false);
function go() {
divEl.innerHTML = ++x;
if (x > 100) {
return false;
}
if (x % 5 == 0) {
setTimeout(function () {
go();
}, 0);
} else {
go();
}
}
function go2() {
x++;
divEl2.innerHTML = x;
if (x > 100) {
return false;
}
go2();
}

clearTimeout() inside setTimeout() method not working in JS

clearTimeout() inside setTimeout() method not working in JavaScript
var c = 0;
var t;
function timedCount() {
document.getElementById('txt').value = c;
c = c + 1;
if (c == 5) {
clearTimeout(t);
}
t = setTimeout(function () {
timedCount()
}, 1000);
}
jsFiddle
You need to prevent the rest of the code of executing, actually you are re-declaring t after clearing the setTimeout. Fiddle
var c = 0;
var t;
function timedCount() {
document.getElementById('txt').value = c;
c = c + 1;
if (c == 5) {
clearTimeout(t);
return false;
}
t = setTimeout(timedCount, 1000);
}
Or just use the else statement:
if (c == 5) {
clearTimeout(t);
// do something else
}else{
t = setTimeout(timedCount, 1000);
}
There will never be a timeout to clear when you call clearTimeout as the last one will have already fired and the next one won't have been set yet.
You want to change your logic so that if (c !== 5) { setTimeout(etc etc) }

Categories

Resources