i am running a setinterval function to check for a payment from coinbase in my react native app, i run the function after every 10 seconds, after the payment has been made, i clear the setinterval and navigate to the homepage, but still the setinteval keeps running how can i stop this?
useEffect(() => {
getData();
myinterval();
}, []);
const myinterval= () => setInterval(function () {
checkCharge();
}, 10000);
const stopCounter = () => {
clearInterval(myinterval);
}
const checkCharge = async () => {
try {
...SOME_CODE_HERE...
stopCounter()
navigation.navigate("HomeScreen");
} catch (e) {
console.log(e);
}
};
i ran into a similar problem some months back, this soluion should work perfectly:
const myinterval = setInterval(function () {
checkCharge();
}, 10000);
but in my case, since I store the setInterval in a variable instead of a function, I had some weird problems, like the setInterval might run three times or keep on running even after I used clearInterval(INTERVAL_NAME); so if you want to check if a payment has been made, create a button that would tell the user to click when they have made the payment, this would be a lot safer than to run the function inside of setInterval
I believe it's because myinterval is assigned to a function and not the actual return value of the setInterval() function. So try to change
const myinterval = () => setInterval(function () {
checkCharge();
}, 10000);
to
const myinterval = setInterval(function () {
checkCharge();
}, 10000);
and then canceling the myinterval variable with clearInterval(myinterval);
You aren't using the return from myinterval() to clear the setInterval. setInterval() returns an id that is used to clear the interval. When you call the function myinterval, it is returning that ID. What you need to do is store that ID in a variable that you can use to clear the interval.
...
function createInterval(){
return setInterval(checkCharge, 10000);
}
function stopCounter(id){
clearInterval(id);
}
...
var id = createInterval();
...
function checkCharge(){
try {
...
stopCounter(id);
...
} catch(e){
console.error(e);
}
}
Related
I have two onclick functions that performing start and stop functions using socket when i click start it start requesting images from server(i am using intervals) when i click stop the server is stopped but the request keep coming to the server. the intervals seems not stopped after clicking kindly review my code
Code:
var interval;
function onclick() {
interval = setInterval(() => {
socket.emit("get_image", "Click");
socket.on('send_image', (message) => {
setImage(message.image);
});
}, 350)
}
function onclicks() {
clearInterval(interval);
setImage(blanked);
}
I have tried to add clearInterval function but it seems not working
Variables declared at the top level of a component are redeclared on each render (here every time you call setImage()) so interval is undefined by the time onclicks() is called.
In order to maintain the value through renders you need to either use state (useState) or a ref (useRef) which won't lose it's value. In this case, since you don't want renders attached to the value of interval a ref is more appropriate. useRef() returns an object with a current property in which your value will be stored.
const interval = React.useRef(null);
function onclick() {
interval.current = setInterval(() => {
socket.emit("get_image", "Click");
socket.on('send_image', (message) => {
setImage(message.image);
});
}, 350);
}
function onclicks() {
clearInterval(interval.current);
interval.current = null; // reset the ref
setImage(blanked);
}
You probably also want to avoid setting multiple intervals. You may already be doing so, but if not you can check if interval is null or not before setting a new one.
const interval = React.useRef(null);
function onclick() {
if (interval.current === null) { // only set new interval if interval ref is null
interval.current = setInterval(() => {
socket.emit("get_image", "Click");
socket.on('send_image', (message) => {
setImage(message.image);
});
}, 350);
}
}
For me, the easiest way to solve this behavior was set the interval as a Ref:
import { useRef } from 'react';
// Initialize the interval ref
const interval = useRef();
// Create the interval
function onclick() {
interval.current = setInterval(() => {
socket.emit("get_image", "Click");
socket.on('send_image', (message) => {
setImage(message.image);
});
}, 350)
}
// Remove the interval
function onclicks() {
clearInterval(interval.current);
setImage(blanked);
}
Using this hook, the component will not re-render when you change the value remove/change the interval.
I am using Angular 10 and have the following setInterval code working in my local:
ngOnInit() {
this.myfunc();
setInterval(this.myfunc.bind(this), 120000);
}
However, the same code is not working on the server.
In other words, myfunc() is not triggering after 2 mins when running on the server.
Debugging Details:
In my local, this.myfunc() is called when the component is loaded for the first time. It is called again after 2 mins as per the setInterval()
However, when running on the server, this.myfunc() is called when the component is loaded for the first time. But it is not called again after 2 mins as per the setInterval()
Problem
setInterval sometimes drifts, as seen in this post.
Solution
Taken from this solution, you would first make a non-drifting class:
function AdjustingInterval(workFunc, interval) {
let that = this;
let expected, timeout;
this.interval = interval;
this.start = function() {
expected = Date.now() + this.interval;
timeout = setTimeout(step, this.interval);
}
this.stop = function() {
clearTimeout(timeout);
}
function step() {
let drift = Date.now() - expected;
workFunc();
expected += that.interval;
timeout = setTimeout(step, Math.max(0, that.interval - drift));
}
}
and then, you would just use this instead for your code:
ngOnInit() {
let ticker = new AdjustingInterval(this.myfunc.bind(this), 120000);
this.myfunc();
ticker.start();
}
I was able to resolve the issue by changing setInterval() to callback as follows:
setInterval(() => {
this.myfunc(); }, 120000);
}
Updated ngOnInit() looks as below:
ngOnInit() {
this.myfunc();
setInterval(() => {
this.myfunc(); }, 120000);
}
}
Why is the setTimeout only being called once?
repeatSubscriber = function(observer) {
observer.next('first');
(function() {
setTimeout(() => {
observer.next('repeating timed resp');
}, 3000);
}());
};
Prints:
first
repeating timed resp
setTimeout() is only supposed to trigger once - what you need is setInterval().
Because it should:
setTimeout() sets a timer which executes a function or specified piece of code once after the timer expires.
More at MDN
What you are looking for is setInterval()
repeatSubscriber = function(observer) {
observer.next('first');
(function() {
setInterval(() => {
observer.next('repeating timed resp');
}, 3000);
}());
};
Because it worked like this its in the function nature,
If you need repeated call you need setInterval function
So I have this code
function timer()
{
setTimeout(function(){alert("Out of time")}, 3000); //Alerts "Out of time" after 3000 milliseconds
}
function resetTime()
{
timer(); //this is not right, i thought it would override the first function but it just adds another timer as well which is not what I want
}
function stopTime()
{
//What could go here to stop the first function from fully executing before it hits 3000 milliseconds and displays the alert message?
}
the function timer() starts as the page loads but if I have a button for stopTime() and I click on it, how do I stop the first function from executing and stop it from hitting the 3000 millisecond mark and alerting "Out of time"?
Use a variable with scope over all of your functions.
var myTimer;
...
myTimer = setTimeout(...);
...
clearTimeout(myTimer);
var timer;
function timer()
{
timer = setTimeout(function(){alert("Out of time")}, 3000); //Alerts "Out of time" after 3000 milliseconds
}
function resetTime()
{
clearTimeout(timer);
timer(); //this is not right, i thought it would override the first function but it just adds another timer as well which is not what I want
}
function stopTime()
{
//What could go here to stop the first function from fully executing before it hits 3000 milliseconds and displays the alert message?
}
try this it will Work For you
Its best to use the useRef hook from React
import {useRef} from 'React';
const function =()=>{
const timerRef = useRef();
const timerFunction =()=>{
timerRef.current = setTimeout(()=>{
//Your Code
},5000);
`
const clearTimerFunction =()=>{
clearTimeout(timerRef.current);
}
}
The value returned from setTimeout is a unique ID that you can use later to cancel the timeout with clearTimeout.
var timeout;
function timer () {
timeout = setTimeout(/* ... */);
}
function resetTime() {
stopTime();
timer();
}
function stopTime() {
clearTimeout(timeout);
}
I have a HTML page with two buttons and I want to use setInterval to evaluate the function multiple times when I click the start button. This works just fine but I can't clear the interval. What am I doing wrong?
function intFunc (func, time) {
interval = setInterval(func, time);
}
$("#startButton").on("click", intFunc(function () {
$.post('link/to/php.php', function(data) {
//do something with data
});
}, 1000));
$("#stopButton").on("click", function () {
clearInterval(interval);
});
First, as the comments suggest you should declare interval above to make sure the scope is clear.
Second, you have a syntax problem. You're invoking intFunc straight away, and passing the result to $("#startButton").on(). This isn't what you want. What you should be passing as that second argument is a callback function. You could reorganize your code like this perhaps:
Third, declaring within a self invoking anonymous function will prevent pollution of the global scope.
(function() {
var interval;
$("#startButton").on("click", function(){
interval = setInterval(function () {
$.post('link/to/php.php', function(data) {
//do something with data
});
}, 1000);
});
$("#stopButton").on("click", function () {
clearInterval(interval);
});
})();
This is how you should (or could) have written it:
var interval;
$("#startButton").on("click", function(){
interval = setInterval(function () {
$.post('link/to/php.php', function(data) {
//do something with data
});
}, 1000);
});
$("#stopButton").on("click", function () {
clearInterval(interval);
});
You cannot use functions like that, because when you write:
$("#startButton").on("click", intFunc(..));
You are executing intFunc immediately, and that doesnt return anything.