So basically I want to call a interval in a function while the function is being runned by another interval. This gives me the result I wasn't expecting. The console log should only be runned every third second but It's not.
My code:
// Define variable test
var test = 1;
// Setting function check on a 1000 ms interval
setInterval(function(){
check();
}, 1000)
// If our variable test is == 1, set another interval on 3000ms on next function
function check() {
if (test == 1) {
setInterval(function(){
execute();
}, 3000)
}
}
// Execute function
function execute() {
console.log("Called every 3rd second!");
}
How can I fix this, spent hours trying to find solution and I'm really exhausted and have no idea how to continue.
If you want to post a answer I really appreciate it! But try not to destroy the structure in the code.
Edit: If you have Chrome, you can run this script in the console. You have to wait a few seconds before it runs.
In case you need to run the function execute after every 3 seconds then you need to replace the first function setInterval with setTimeout. I am not sure why you need setInterval for the calling the check function.
Try out this code:
var test = 1;
// Setting function check on a 1000 ms interval
setTimeout(check, 1000)
// If our variable test is == 1, set another interval on 3000ms on next function
function check() {
if (test == 1) {
setInterval(execute, 3000)
}
}
// Execute function
function execute() {
console.log("Called every 3rd second!");
}
Related
My setTimeout() function works, but my clearTimeout() is not working. Even though I have an 'if' statement that's supposed to run the clearTimeout function once my variable 'secs' is less than 0, the timer keeps counting down into negative numbers. When I type my variable name, 'secs' into the console, I get undefined, even though it's defined as a parameter in the function called by my setTimeout. I don't know what I'm doing wrong. Can anyone help, please?
My full code is at https://codepen.io/Rburrage/pen/qBEjXmx;
Here's the JavaScript snippet:
function startTimer(secs, elem) {
t = $(elem);
t.innerHTML = "00:" + secs;
if(secs<0) {
clearTimeout(countDown);
}
secs--;
//recurring function
countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);
}
Add a condition to call recursive function like below.
if (secs < 0) {
secs = secsInput;
}
//recurring function
countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);
For a countdown timer, I would recommend using setInterval and clearInterval instead. setInterval will repeatedly run the callback function for you. It might look like this:
let countdown;
function startTimer(secs, elem) {
countdown = setInterval(function(){
t = $(elem);
t.innerHTML = "00:" + secs;
secs--
if (secs < 0) {
clearInterval(countdown);
}
}, 1000);
}
By the time you call clearTimeout(countDown), countDown refers to the previous timeout, that already timed out. It will not stop the one yet to start. You could just not re set the timeout, like
if(!/*finished*/) setTimeout(startTimer, 1000, secs, elem);
In your case, it's more convenient to use setInterval and clearInterval.
To keep the setTimeout and clearTimeout functions, you should add return in the if statement.
function startTimer(secs, elem) {
t = $(elem);
t.innerHTML = "00:" + secs;
if(secs<0) {
clearTimeout(countDown);
return;
}
secs--;
//recurring function
countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);
}
So there are 4 events in my opinion that will have to be addressed by the timer:
The quiz starts
The quiz ends
The timer runs out
The player answers a question
This can be solved by a function returning an object with some options.
The createTimer can be used to set the parameters for the timer.
Point 1. would be timer.start() --> will start a timer with the parameters
Point 3. can be addressed with the callback that will be called if the timer runs out --> createTimer(5,'display', ()=>{ // your code goes here })
Point 2. can be achieved with --> timer.stop()
Point 4. is needed when the timer needs to be reset without running out timer.reset()
Further on the interval is not in the global scope so you could have multiple timers with different settings and they wouldn't interfere with each other
// function for creating the timer
function createTimer(seconds, cssSelector, callbackOnTimeout) {
// interval the timer is running
let interval;
// the html node where innerText will be set
const display = document.getElementById(cssSelector)
// original seconds passt to createTimer needed for restart
const initSec = seconds
// starting or continuing the interval
function start() {
// setting interval to the active interval
interval = setInterval(() => {
display.innerText = `00:${seconds}`;
--seconds;
if (seconds < 0) {
// calling restart and callback to restart
callbackOnTimeout()
restart()
}
}, 1000);
}
// just stopping but not resetting so calling start will continue the timer
// player takes a break
function stop(){
clearInterval(interval)
}
// opted for a restart and not only a reset since it seemed more appropriate for your problem
function restart(){
clearInterval(interval)
seconds = initSec
start()
}
// returning the object with the functions
return {
start: start,
stop: stop,
restart: restart
}
}
// example for creating a timer
const timer1 = createTimer(5,'display',()=>{
console.log(`you where to slow ohhh...`)
})
// calling the timer
timer1.start()
I want to execute a function every specified seconds, and it should loop forever. When the function is finished I want to start a new setTimeout using a random generated value between 2 and 5 (represents seconds).
Maybe badly explained but..
this is what I have so far.
function Start() {
let count = $("section.mosaic").find("a.item").length;
ChangePic();
setTimeout(function () {
let interval = CREATOR.PUB.Utility.randomInterval(2, 5);
console.log(interval);
}, 3000);
function ChangePic() {
}
}
Move the interval code into ChangePic so that it can call itself when it finishes.
function Start() {
let count = $("section.mosaic").find("a.item").length;
ChangePic();
function ChangePic() {
// do stuff here
let interval = CREATOR.PUB.Utility.randomInterval(2, 5);
setTimeout(ChangePic, interval * 1000);
}
}
Note that this will call ChangePic once immediately when Start runs, and the random intervals will begin thereafter. If you need the initial execution to be on a delay as well, you could either copy the timeout code and run it instead of calling ChangePic();, or move it into a helper function that you call both inside Start and ChangePic.
I have this code:
function toStop(){
while(true){}
}
toStop();
Now, how can I stop this? Or how can I kill the current thread if this function call is somewhere in the setInterval running thread? Example:
var id = setInterval(function(){
toStop();
}, 1000);
//stop thread/timer with id here.
clearInterval doesn't work because it waits until the function call ends.
Thanks!
"Can I stop the execution of a function from outside that function?"
No, you can't programmatically.
JavaScript is single-threaded and if you run a piece of code that makes it infinitely busy, such as while(true);, then nothing else will ever be able to execute.
Calling such a piece of code within setTimeout or setInterval will have the same result, since the callback of these gets executed in the only thread we have as well.
However, you can create a timed recurring execution using setInterval or setTimeout, which can be stopped.
var timerId = setInterval(function () {
//Process an iteration of the loop in here
//If you cause an infinite loop in here, you will have the same issue
}, 50);
//stop the timer after ~3 seconds
setTimeout(clearInterval.bind(null, timerId), 3000);
Notes:
4 is the lowest interval that could be honored as specified in the SPEC.
setInterval will stack if the callback takes more time to execute than the specified interval. For that reason I never use setInterval and always use setTimeout.
Timer intervals are not guaranteed to be accurate
e.g. with setTimeout
var stopProcessing = startProcessing();
//Stop processing after ~3 seconds
setTimeout(stopProcessing, 3000);
function startProcessing() {
var timerId;
!function process() {
//Do some processing
//Continue processing in ~50 ms
timerId = setTimeout(process, 50);
}();
return function () { clearTimeout(timerId); }
}
Instead of an infinite loop, just use an if statement and wrap it in an interval:
var shouldContinue = true;
var interval = 0;
function toStop() {
if (interval == 0) {
interval = setInterval(function() {
if(shouldContinue) {
...
}
else {
clearInterval(interval);
interval = 0;
}
}, 200); // Or whatever interval makes sense
}
}
toStop();
// ...
shouldContinue = false;
See this principle in action here.
No, you can't programmatically, as #plalx said but you could try this: declaring a binding outside and check on that to continue or stop the loop:
let letMeGoOut;
function toStop(){
while(letMeGoOut != false)
}
toStop();
Here, I've created a function on mouseover that triggers a loop changing the opacity of the h1. It goes on till the mouse cursor moves out and is over something else in the page.
Here is the example: https://codepen.io/Mau-Di-Bert/pen/VqrRxE
I was reading one book named 'Hands on node.js' by 'Pedro Teixiera'.
I was trying to execute one same program giving in that book that will call a function and that function is calling the same function recursively within some interval again and again.
But when I executed, it gives only one time '1' and stops
Please help me to figure it out why it is not able to call the same function again.
Sample program is as follows:
var schedule = function(timeout, callbackfunction) {
return {
start: function() {
setTimeout(callbackfunction, timeout)
}
};
};
(function()
{
var timeout = 10000; // 1 second
var count = 0;
schedule(timeout, function doStuff() {
console.log(++ count);
schedule(timeout, doStuff);
}).start(timeout);
})();
You aren't actually calling the function again. start() is the part that starts the timer.
schedule( timeout, function doStuff() {
console.log( ++count );
schedule( timeout, doStuff ).start(); // <--- added .start() here
}).start();
(Also note that the start() function doesn't take parameters.)
with some interval again and again
No, for that you would have used setInterval instead of setTimeout.
it gives only one time '1' and stops
Yes, your doStuff function doesn't put a new timeout. Your odd schedule function needs to be .start()ed!
I created a loop with setTimeout function and it comes to a problem after 2nd or 3rd step it call's itself because it starts excecuting twice at the time. This is what my function looks like:
var value = 70,
intervalID = null;
function interval() {
intervalID = setTimeout(countDown, 1000);
}
function countDown() {
value--;
if(value > 0) {
clearTimeout(intervalID);
interval();
} else {
endInterval();
}
}
function endInterval() {
// do something
}
If I console the variable value its 69, 68 and after that it starts decreasing variable value twice in one function call. I'm not calling function countDown() anywhere but from one place.
What could be the problem?
Edit: this code works now.
I'd recommend you to "sanitize" the timeouts by stopping previous one.
function interval() {
clearTimeout(intervalID);
intervalID = setTimeout(countDown, 1000);
}
However it looks like control of symptoms instead of sickness' cause. So it would be better to detect the cause of the issue.