I'm making a slot machine simulator to learn javascript and messing around with setInterval() and clearInterval(). To simulate the slow stopping of the rows I set asetTimeout() to clear the Intervals of my 3 columns, but the timer doesn't reset the function is still called, I also tried a console log inside the setTimeout and the calls are correct 1sec after 2sec another log and then the third. what I'm doing wrong?
Here try the game and the full code with HTML: https://jsfiddle.net/orphtv1m/1/
//Here i initialize my setInterval
wheelIntervals[i] = setInterval(function(){
columns[i][numberStart[i]].style.background = "white";
numberStart[i] = (numberStart[i]+1)<10 ? numberStart[i]+1 : 0;
columns[i][numberStart[i]].style.background = "red";
},timer);
/*Code*/
setTimeout(function(){
//Here i try to clear it
console.log('Helo');
clearInterval(wheelIntervals[i]);
},i*1000);
}
setTimeout(endGame(), 3000);
}); ```
clearInterval(wheelInterval[i])
Will be always called with i equal to 2
Using setTimeout inside loops might be a little bit tricky because of closures.
Here is an explanation how to do it correctly: https://medium.com/#axionoso/watch-out-when-using-settimeout-in-for-loop-js-75a047e27a5f
Related
I'm writing a "Game of Life" in javascript. I have all the logic done in a function called doGeneration(). I can repeatedly call this from the console and everything goes as planned, however, if I put it in a while loop the execution blocks the UI and I just see the end result (eventually).
while (existence) {
doGeneration();
}
If I add a setTimeout(), even with a generation limit of say 15, the browser actually crashes (Canary, Chrome).
while (existence) {
setTimeout(function() {
doGeneration();
},100);
}
How can I call doGeneration() once every second or so without blocking the DOM/UI?
You want setInterval
var intervalId = setInterval(function() {
doGeneration();
}, 1000);
// call this to stop it
clearInterval(intervalId);
I would use requestAnimationFrame(doGeneration). The idea of this function is to let the browser decide at what interval the game logic or animation is executed. This comes with potential benefits.
https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/
Rather than using setINterval or setTimeout and assume some random time interval will be enough for the UI to update you shoul/could make the doGeneration smart enough to call itself after dom was updated and if the condition of existence is satisfied.
So I'm attempting to make a Pomodoro Timer without using an API (I know, stupid choice) but I feel as if I'm over-complicating this issue.
I forked my CodePen so I could post the current code here without confusing anyone. My Code Pen
To see my issue: Just set Timer to .1 and Break to .1 - You'll see the Start to Resume works fine, but the Resume to start has issues.
I built in consoleLogs to track it and I see the Work Timer TRIES to start but then breakTimer over-runs it, and duplicates on every pass.
Why isn't my clearInterval working?
Things I've tried:
Adjusting names of clearInterval,
Setting it so it goes back to startTimer instead of start
force quitting it (instead of looping it back to startInterval.
The function is virtually identical to my startFunction yet fails to work properly. Would appreciate any input (I'm new to clearInterval but I believe I am using it right.)
function breakTimer() {
$('.jumbotron').css('visibility', 'visible');
setInterval(function() {
console.log("Break Timer...");
breakTime--;
if (breakTime < 0) {
clearInterval(timer);
working = false;
start();
} else {
showTime(breakTime);
}
}, 1000);
}
Edit:
To answer the reply:
function start() {
if (working == true){ //This keeps it from being spammable
return;
} //Else
workTime = $('#work').val()*60;
breakTime = $('#break').val()*60;
working = true;
checkStatus();
timer = startTimer();
}
Unsure if I should post every Function here
As per definition, the value returned by setInterval(...) is the ID of the created timer. As such, with your code you can only stop the last created timer because the ID in the timer variable gets overwritten, causing it to lose control over the previously created (and still running) timers.
The ID is what you pass on to clearInterval(...) to stop a timer. You will have to do this in a different way. You may ask for a different way in https://codereview.stackexchange.com/
I tried the answer here: Resetting a setTimeout, but it doesn't seem to be working for me.
I'm building a catalog viewer using Owl Carousel. I have a function set to go off on the afterMove event handler that shows what page the user is on. It displays the page counter and then sets a timeout to have it fadeout after 1 second. Probably is lots of people go through pages faster than once per second. So, I need to reset the timeout if the function gets called again.
function showCounter(){
var $counter = $('#counter');
//clear timeout
window.clearTimeout(timeout);
//Display counter
$counter.show();
//set timeout
var timeout = window.setTimeout(function(){
$counter.fadeOut(500);
}, 1000);
}
But window.clearTimeout(timeout) doesn't seem to be working and I'm not sure why
Thanks
var timeout inside the function makes timeout local to the function; thus, every time you call showCounter, timeout is undefined. Move the variable declaration out of the function:
var timeout;
function showCounter() {
// ...
timeout = // NO VAR! ...
// ...
}
Here's a simple html&javascript: When I click on the "start" button, the counter starts, the number displayed being incremented, then when I click on the "start" again, the counter resets and starts all over again. (This is just a practice with setTimeout and I don't intend to use this as anything.) At first I forgot to stop mainloop and was running another mainloop every time the button is clicked, which resulted in accelerated counting after repeated clicks. I saw this question (javascript - How to stop a setTimeout loop?) and managed to make it work.
And then I changed the javascript slightly. I thought these codes are almost equivalent, but it wasn't --- it no longer worked, multiple mainLoop seemed to be running after clicks. My question: why are these not equivalent? Why isn't the latter working?
Working codes:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
<pre id="start" style="background-color:green; width:70px; text-align:center;">Start</pre>
<pre id="count"></pre>
</div>
<script src="main.js"></script>
</body>
</html>
main.js
var counter = 0;
var timer;
function mainLoop(){
counter++;
document.getElementById("count").innerHTML=counter;
timer = setTimeout(mainLoop,100);
}
function start(){
if (timer){
// stop mainLoop that is currently running.
clearTimeout(timer);
}
// and start again.
counter = 0;
mainLoop();
}
document.getElementById("start").addEventListener("click",start);
Then I changed:
var counter = 0;
var timer;
function mainLoop(){
counter++;
document.getElementById("count").innerHTML=counter;
return setTimeout(mainLoop,100); // changed here
}
function start(){
if (timer){
clearTimeout(timer);
}
counter = 0;
timer = mainLoop(); // and here
}
document.getElementById("start").addEventListener("click",start);
mainLoop is Looping itself, without setting the timer that's why.
Every-time the setTimeout get a new value , while you are stopping a old Timer if you don't update it.
You may wanna look into setInterval() instead thou, don't need repeatedly create Timer.
Your code will work the first time mainLoop is called as the value is returned. The second time it is called it is called from setTimeout, which means that the returned value (the value of the new timeout) is lost.
When you try to clear the timeout, you're trying to clear it using the value obtained from the very first call, which is a timeout which is passed in any case, not the current timeout value.
Try setting timer in your mainLoop.
You execute clearTimeout(timer)
before you set timer = mainLoop();
also i believe timer = mainloop() just runs the mainLoop function again timer is only the timeout function..
it look's like you're using setTimeout as an interval maybe you should look at this..
jQuery setInterval()
The reason you are getting multiple mainLoop's is because in the mainLoop, you are telling it to call itself every 100 milliseconds. Then it's returning setTimeout to itself, instead of returning it to the start method.
So you end up calling setTimeout more than once, but you arent storing the return value, which you need to pass to clearTimeout to cancel the loop.
What you could do is have something like the following:
function mainLoop() {
counter++;
document.getElementById("count").innerHTML=counter;
}
function start() {
if (timer){
clearTimeout(timer);
timer = undefined;
counter = 0;
} else {
timer = setInterval(mainLoop(), 100); // Set interval calls it every 100 milliseconds until it is cancelled
}
document.getElementById("start").addEventListener("click", start, false);
so im a little new to javascript, but im trying to make a progress bar, with some other functionalities, on click of a button. im tring to use the set interval in javascript in order to time the bar, this is my js so far:
//Javascript Document
function progress(){
Var uno = setTimeout("uno()", 3000);
uno(){
document.getElementById("title").innerHTML = "Connecting...";
document.getElementById("progressInner").style.display = 'block';
document.getElementById("progressInner").style.width = '20px';
}
}
From what i have gathered this is how it works, however i am skeptical as it seems i am setting a variable uno but not doing anything with it.... from my background in php, thats not how that works :p any pointers you guys can give me on this? my html is here: http://jsbin.com/apoboh/1/edit
right now, it does nothing, it gives me : Uncaught ReferenceError: progress is not defined
first, you are using setTimeout not setInterval. The former fires the callback once, the latter indefinitely at a set interval.
Second, these methods return a token that you can use to cancel a setInterval, do this instead
function startProgress(){
// only start progress if it isn't running
if (!App.progressToken) { // App is you apps namespace
App.progressToken = setInterval(function(){
document.getElementById("title").innerHTML = "Connecting...";
document.getElementById("progressInner").style.display = 'block';
document.getElementById("progressInner").style.width = '20px';
}, 3000);
}
}
later, when you want to stop:
function stopProgress(){
clearInterval(App.progressToken);`
delete App.progressToken
}
The variable uno simply holds the handle to the timeout that you just set. You can later use it to clear the timeout before it executes if you need to via a call to clearTimeout().
If you don't need to clear the timeout, then there's really no reason to store the handle at all.
function progress(){
function uno(){
document.getElementById("title").innerHTML = "Connecting...";
document.getElementById("progressInner").style.display = 'block';
document.getElementById("progressInner").style.width = '20px';
}
var timeoutFunc = setTimeout(uno, 3000);
}
You pass a function to setTimeout which it will call later, not a string. So this code will define a function uno, and then pass it to setTimeout and delay 3 seconds then call it every 3 seconds after that.
You forgot to put word "function " before uno()