Using setTimeout for a counter creates a strange output? [duplicate] - javascript

This question already has answers here:
setTimeout with loop issue with field update
(2 answers)
Closed 8 years ago.
I checked, doubled checked and rechecked this code to make sure it works properly (and it's simple) yet I cannot figure out why I get ~count: 17k for the output, please help...
Thanks
<html>
<head>
</head>
<body onload = "counter()">
<script type="text/javascript">
var count = 0;
function counter()
{
document.getElementById("div_1").innerHTML = "count: "+count;
count++;
setTimeout(counter(), 1000);
}
</script>
<div id = "div_1"></div>
</body>
</html>

Do not call, just reference
setTimeout(counter, 1000);

you are passing the result of counter() into setTimout, instead of just setTimeout(counter, 1000). effectively, its just a recursive function. what you are doing is this:
var count = 0;
var counter = function(){
count++;
//Don't flood the console
//console.log(count);
document.querySelector("#div1").innerHTML = "count: " + count;
//you probably don't want this
counter();
//but this
//setTimeout(counter, 1000);
};
your result of 17k is where count was at when javascript exhausted its call stack

Wrap function in an anonymous function
setTimeout(function(){counter()}, 1000);
http://jsfiddle.net/tgLqH/

Related

Changing style property while js code is running [duplicate]

I'm trying to refresh a div from Javascript at each loop and see 1, 2, 3, ....
The following code works, but only displays the final result (9998).
How is it possible to display all the steps?
Thank you in advance.
<html>
<head>
</head>
<body>
<div id="cadre" style="width=100%;height=100%;">
<input type="button" value="Executer" onclick="launch();"/>
<div id="result" ></div>
</div>
<script type="text/javascript">
function launch(){
for (inc=0;inc<9999;inc++){
document.getElementById('result').innerHTML = inc;
}
}
</script>
</body>
</html>
JavaScript execution and page rendering are done in the same execution thread, which means that while your code is executing the browser will not be redrawing the page. (Though even if it was redrawing the page with each iteration of the for loop it would all be so fast that you wouldn't really have time to see the individual numbers.)
What you want to do instead is use the setTimeout() or setInterval() functions (both methods of the window object). The first allows you to specify a function that will be executed once after a set number of milliseconds; the second allows you to specify a function that will be executed repeatedly at the interval specified. Using these, there will be "spaces" in between your code execution in which the browser will get a chance to redraw the page.
So, try this:
function launch() {
var inc = 0,
max = 9999;
delay = 100; // 100 milliseconds
function timeoutLoop() {
document.getElementById('result').innerHTML = inc;
if (++inc < max)
setTimeout(timeoutLoop, delay);
}
setTimeout(timeoutLoop, delay);
}
Notice that the function timeoutLoop() kind of calls itself via setTimeout() - this is a very common technique.
Both setTimeout() and setInterval() return an ID that is essentially a reference to the timer that has been set which you can use with clearTimeout() and clearInterval() to cancel any queued execution that hasn't happened yet, so another way to implement your function is as follows:
function launch() {
var inc = 0,
max = 9999;
delay = 100; // 100 milliseconds
var iID = setInterval(function() {
document.getElementById('result').innerHTML = inc;
if (++inc >= max)
clearInterval(iID);
},
delay);
}
Obviously you can vary the delay as required. And note that in both cases the inc variable needs to be defined outside the function being executed by the timer, but thanks to the magic of closures we can define that within launch(): we don't need global variables.
var i = 0;
function launch(){
var timer = window.setInterval(function(){
if( i == 9999 ){
window.clearInterval( timer );
}
document.getElementById('result').innerHTML = i++;
}, 100);
}
launch();
Try
document.getElementById('result').innerHTML += inc;

Javascript loop only runs once [duplicate]

This question already has answers here:
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 2 years ago.
Trying to make a react native app that takes text as input and converts it to morse code, using the phone's torch. I can get the translated morse code but when I try to convert that to light using the torch, the loop only runs once (There is a short flash) and then exits. Why is that happening/how do I fix that?
var j;
for(j = 0; j < cipher.length; j++) {
if(cipher[j] == '.') {
Torch.switchState(true);
setTimeout(function(){Torch.switchState(false)},200);
setTimeout(function(){},200);
}
else if(cipher[j] == '-') {
Torch.switchState(true);
setTimeout(function(){Torch.switchState(false)},600);
setTimeout(function(){},200);
}
else if(cipher[j] == ' ') {
setTimeout(function(){},600);
}
else {
setTimeout(function(){},1400);
}
}
The setTimeout() function needs a callback function to work. I guess that if you put the "if" conditionals into the callback functions it will work. I'll leave a example down here:
HTML:
<p>Live Example</p>
<button onclick="delayedAlert();">Show an alert box after two seconds</button>
<p></p>
<button onclick="clearAlert();">Cancel alert before it happens</button>
Javascript:
var timeoutID;
function delayedAlert() {
timeoutID = window.setTimeout(window.alert, 2*1000, 'That was really slow!');
}
function clearAlert() {
window.clearTimeout(timeoutID);
}
Another possibility is to use an anonymous function to call your callback, but this solution is a bit more expensive. Example:
var intervalID = setTimeout(function() { myFunc('one', 'two', 'three'); }, 1000);
Checkout the Official Guides in: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

javascript setInterval only work once? [duplicate]

This question already has answers here:
Why does the setInterval callback execute only once?
(2 answers)
Closed 4 years ago.
i need to show current time in html code, but the javascript code only work once?
$(document).ready(function () {
function updateClock(ele){
var current_time = new Date();
var current_time_str = current_time.toLocaleTimeString();
ele.text(current_time_str);
console.log(current_time_str);
}
setInterval(updateClock($('#clock')) , 1000 );
})
It's work different some others languages like C,Object-C or Python, it's so misleading for me.
You need to wrap the calling part in a function, because it is called only once and returns undefined as calling value.
setInterval(() => updateClock($('#clock')), 1000);
Another possibillity is to use the third and following arguments of setInterval
setInterval(updateClock, 1000, $('#clock'));
Put the updateClock inside setInterval callback function
$(document).ready(function() {
function updateClock(ele) {
var current_time = new Date();
var current_time_str = current_time.toLocaleTimeString();
ele.text(current_time_str);
}
setInterval(function() {
updateClock($('#clock'))
}, 1000);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clock"></div>

JavaScript Call function then call it after x seconds continuously [duplicate]

This question already has answers here:
Execute the setInterval function without delay the first time
(18 answers)
Closed 5 years ago.
Following calls a functions every 10 seconds.
It does not call the function immediately, just after the first 10 seconds.
window.setInterval(function(){
/// foo
}, 10000);
How do I call the function first, then call it every x seconds, what would be the best way of doing this?
Either give it a name and call it right after the setInterval
function repeat(){
//foo
}
window.setInterval(repeat, 10000);
repeat();
Or use setTimeout instead and call it from inside the function
function repeat(){
//foo
setTimeout(repeat, 10000);
}
repeat();
EDIT:
<html>
<head><title>Timeout testing</title></head>
<body onload="callMe()">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
function callMe()
{
window.console.log('called');
window.setTimeout(callMe, 1000);
}
$(".realContent").click(function() {
var data = [ {"id":1,"start":"/Date(1401993000000+0530)/"} ];
var myDate = new Date(data[0].start.match(/\d+/)[0] * 1);
myDate = new Date(myDate.getTime() + myDate.getTimezoneOffset() * 60 * 1000);
alert(myDate);
})
</script>
</body>
</html>

setTimeout in a loop: callbacks happen with no delay between them [duplicate]

This question already has answers here:
All the setTimeouts inside javascript for loop happen at once
(2 answers)
Closed 10 years ago.
I searched around and found some others with similar issues, but I can't seem to find a solution or clear explanation.
var content = 'test<br />';
for( var i = 1; i < 6; i++ ) {
setTimeout(function() {
document.write(content);
}, 3000);
}
I'd like the code in the for loop to execute 5 times, with a three second delay between each loop. When it runs it, at least on the surface, looks like a three second delay at page load, then goes through all the loops with no delay.
What am I missing?
Your problem is that all the calls are happening after 3000 ms. Do perform each call 3s apart do this:
var content = 'test<br />';
for( var i = 1; i < 6; i++ ) {
setTimeout(function() {
document.write(content);
}, 3000 * i);
}
You probably need to use setInterval ('cause you're trying to run code at a certain "interval")
// first create an isolated namespace because we don't need to dirty the global ns //
(function(){
var counter = 0;
var maxIterations = 6;
var intervalReference = setInterval(function(){
// your code goes here //
alert('test');
// the stop condition //
++counter;
if (counter == maxIterations) {
clearInterval(intervalReference);
}
}, 3000);
}())
setInterval is probably the way to go (see Alin's answer) but if you were wanting to go down the setTimeout route, the code would look something like this:
var loop = 0;
var content = "test<br>";
function startTimeout(init){
if(init!==true){
document.write(content);
loop++;
}
if(loop<5){
setTimeout(startTimeout, 3000);
}
}
startTimeout(true);

Categories

Resources