for loop delay in javascript - javascript

How to set delay in for loop execution
for(i=0; i<=10;i++){
var s=i;//This line should execute for every 2 secs only
}
How to give loop delay in java script....
I dont want like below..I want without using setTimeout...
for(i=0; i<=10;i++){
setTimeout("setvalue()",2000); //This alert should display for every 2 secs only
}
function setvalue()
{
var s=i;
}
please help me...

Use setInterval()
var i = 0;
var interval = setInterval(function(){
setValue();
i += 1;
if(i == 10)
clearInterval(interval);
}, 2000);
There is no way to sleep for 2sec without freezing the whole browser. Javascript is single threaded.

You can't. JS runs in a single thread and any attempt to delay that thread will freeze the entire page. Using setTimeout is your only option.
EDIT: or setInterval; either way, there is no non-hairy way to express "halt execution here for x milliseconds."

Using setTimeout is inevitable, however, a recursive function might be a better solution for this one:
var i=0;
function recurs() {
i = s;
i++;
if (i <= 10) recurs();
}
recurs();

As others have stated, setTimeout can be used very well to handle these sorts of scenarios and setInterval could also be used but is discouraged by some.
You can even recursively call a function that has setTimeout built into it as mentioned in the MDN documentation of setInterval. The heading there mentions 'dangerous usage' but their solution to the danger is the block of code beneath.
There it mentions that to have a loop executing every x seconds (or milliseconds) then you can do the following and know for sure that the functions will only be executing one at a time and in-sequence:
(function loop(){
setTimeout(function(){
// logic here
// recurse
loop();
}, 1000); // repeat loop 1 second after this branch has completed
})();
And if you want it to only do that a limited number of times, then you can create a variable outside of the loop and only recursively execute if the count is smaller than the number of times you want to execute for. Such as this:
var count = 0;
(function loop() {
setTimeout(function() {
// logic
count++;
if (count < 10) {
loop();
}
}, 1000);
})();

Related

javascript code hanging the page

I am trying to get the position of a moving div(animated using css3 animations) and for checking it continuously I am using a while(true) like below
function detectCollision(){
alert(document.getElementById("obstacle").style.left)
while(true){
var temp = getObstaclePosition();
var temp2 = getPlanePosition();
if(temp[0] <= temp2[0]+500){
document.getElementsByClassName("plane")[0].style.display = "none";
break;
}
}
}
The problem here is that after the first alert the page hangs. Moreover if I put an alert in the while loop then it keeps on popping up and the code works fine but not otherwise.
Let me know how I can fix this?
Instead of using a while (true), which is costly, you can use setInterval:
a = setInterval(function () {
var temp = getObstaclePosition();
var temp2 = getPlanePosition();
if(temp[0] <= temp2[0]+500){
document.getElementsByClassName("plane")[0].style.display = "none";
clearInterval(a);
}
}, 100);
The page does not render while you are inside that loop, and thus the position of the element will not change. This results in the loop never ending.
If you want to do something like this, you will have to be using a recursive setTimeout or a normal setInterval implementation.
With them, do one check per timeout.
https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
JavaScript runs in one and the same thread, so if some loop occupies this with an infinite loop, the rest is not able to run anymore.
As an alternative to your loop, you could use setInterval, which repeatedly executes a function or code snippet:
setInterval(new function() {
// whatever
}, 100); // repeat every 100 ms, i.e. 10 times per second

How would I make a stopwatch in Javascript/jQuery? [duplicate]

This question already has answers here:
How to create a stopwatch using JavaScript?
(7 answers)
Closed 8 years ago.
How would I make a stopwatch in Javascript/jQuery?
I have developed a few methods of my own, here is one using while loops. This stopwatch is merely meant to count for a minute.
function myStopwatch() {
var $count = 0;
while($count < 60) {
$count++;
}
$count.delay(1000); //makes $count one second long
}
myStopwatch()
Using setInterval() may be better idea:
var count=0;
var timer = setInterval(function(){
if(count<60) count++;
else clearInterval(timer);
},3000);
Use setInterval...
var count = 0;
doEverySecond(){
// something to do every second...
count++;
if(count > 60) clearInterval(timer);
}
var timer = setInterval(doEverySecond, 1000)
jQuery's .delay() does not halt the execution of javascript like you're trying to do. It only works with asychronous operations that use the jQuery queue system such as animations which means it will do nothing in your current code since you are not using any jQuery queued operations.
In javascript, the way that you "delay" for one second is to use setTimeout() or setInterval() and specify the callback function that you want called at some future time from now.
setTimeout(function() {
// this code here will execute one second later
}, 1000);
// this code here executes immediately, there is no delay
var x = 1;
So, if you want to wait for something for a minute, you would do this:
// execute some code one minute from now
setTimeout(function() {
// this code here will execute one second later
}, 1000*60);

SetInterval inside a Closure, inside a For loop, creates too many intervals, won't stop running

I've got some rather complicated logic:
var myArray = [];
var tempInterval = 0;
// Run for 6 minutes
for(i=0;i<360;i++) {
// Closure so that 'i' is the right value when setInterval runs
tempInterval = (function(i) {
interval1 = setInterval(function() {
console.log(i);
}, (i * 1000));
return interval1;
})(i);
// Put the setInterval value into an array
myArray.push(tempInterval);
}
I use a Closure because I need the value of i to be 0,1,2,...etc, and if you don't use a closure, it'll be 360 by the time the interval executes.
If you run that in your console, you'll see it runs way more than 360 times. For some reason, it's creating too many intervals.
I want to have a function to stop this execution of setIntervals:
for(i=0; i<myArray.length; i++) {
clearInterval(myArray[i]);
}
But, because it creates too many, I can't get it to stop.
For example, if you run it inside for(i=0; i<5; i++) instead of for(i=0;i<360;i++), you'll see, it still runs indefinitely.
Why is it creating so many intervals, and how do I get it to run only 360 times? Also, is that the right way to save the intervals, so I can use clearInterval to stop their execution?
The problem
setInterval does not mean "sleep", it means "Run this function every time period".
Each of the 360 times you go around the loop, you call setInterval saying "Run this function every i seconds.
So you get 360 countdowns, each of which runs a function when it hits zero before restarting the countdown to run the function again.
The solution
Don't use setInterval. Use setTimeout.
Or, alternatively:
I'd generally avoid setting 360 timers running at once and instead do something like:
var i = 0;
function next() {
console.log(i);
i++;
if (i < 360) {
setTimeout(next, 1000);
}
}
next();

calling function in a loop in javascript

I am trying to call a function from within a loop in a way that when the function finishes executing, the loop continues to the next iteration and calls it again. But instead the loop doesn't wait for the function to finish and instead calls 4 instances of the function and runs them at the same time! Should I put the whole function in the loop or is there to make the loop wait for the function to be executed? Thanks
for (var i=2; i<=4; i++){
galleryAnimation(i); //This is executed 3 times at once
}
function galleryAnimation(i){
$("#pic" + i).delay(delayTime).fadeIn(duration);
}
The function is being executed 3 times just like you requested, the problem is that both delay and fadeIn use timers: they set a timer in the future when the function will be executed and return immediately: they are non-blocking calls. So, in your case, because you're calling the function 3 times at, let's say, 0.0001s, 0.0002s, and 0.0003s, the three kick in at, let's say, 5.0001, 5.0002 and 5.0003.
What you had in mind were blocking calls to these functions. You expected the whole execution to stop until the animations were finished. This would stop the whole browser Javascript engine for the duration, meaning no other animation or user javascript interaction would be possible.
To solve it, you have to use callbacks. You can supply a function to fadeIn that will be called once the animation has completed:
http://api.jquery.com/fadeIn/
You can use queues to simulate the same on delay():
Callback to .delay()
Simplistic solution: Increase the timeout by a factor every time.
var i, factor,
duration = 250,
delayTime = 500;
for (i = 2, factor = 0; i <= 4; i++, factor++) {
galleryAnimation(i, factor);
}
function galleryAnimation(i, factor) {
$("#pic" + i).delay(factor * delayTime).fadeIn(duration);
}
This runs the same way your approach does, only the delays get longer every time.
Generic solution 1 - work with setInterval() to have your worker function (the one that does the fadeIn) called in predefined intervals:
var elements = $("#pic2,#pic3,#pic4").toArray(), // or any other way to select your elements
duration = 250,
delayTime = 500,
intervalId = setInterval(function () {
$(elements.shift()).fadeIn(duration);
if (elements.length === 0) {
clearInterval(intervalId);
}
}, delayTime);
Generic solution 2 - work with callbacks that are called when the previous animation finishes:
var elements = $("#pic2,#pic3,#pic4").toArray(), // or any other way to select your elements
duration = 250,
delayTime = 500,
next = function () {
$(elements.shift()).delay(delayTime).fadeIn(duration, next);
};
next(); // start the chain
one thing you can do, is to use an identifier (boolean) and then, in the loop, you test the identifier to decide if the loop can continue or stop.
For example,
function galleryAnimation(i, iBool){
$("#pic" + i).delay(delayTime).fadeIn(duration);
iBool = 0;
}
Then on the return;
for (var i=2; i<=4; i++){
galleryAnimation(i, iBool);
// If iBool = 0 then continue
// Else Break
}
that might be a solution, as the loop will need the returning value to determine the next step, to continue or break.
I came with my own solution that seemed to work perfectly, this is my code:
function fadeInAnimation(index){
$("#pic" + index).delay(delayTime).fadeIn(duration, function(){
photoIndex();
});
}
function photoIndex(){
index++;
fadeInAnimation(index);
}
fadeInAnimation(index);
});
I have realized that using loops is a really bad idea with things like this. This code will allow me to add as many images as I want just by renaming them in the folder rather than coding them in manually as callbacks for each photo.
Thanks for those who answered. Your suggestions are great and will definitely remember them in other applications like this one

FOR Loop count up

I have the following code, I am trying to simply count to ten using a FOR loop Through each iteration I want to use jQuery to update a div element with the value of i
for (i=0;i<=10;i++){
setTimeout(function(){
$(".test").html(i);
},10000);
}​
JSFIDDLE
The problem is, the loop will execute and not display anything until finished, which will simply be the number 10.
Is there a way to achieve what I need?
Thank
Your code doesn't work as expected because of closure effect. It is usually solved by creating another anonymous function that is called right after it is created:
for (i=0;i <= 10;i++){
(function(i) {
setTimeout(function(){
$(".test").html(i);
}, i * 1000);
})(i);
}​
http://jsfiddle.net/zerkms/GgzFW/4/
demo jsFiddle
var i = 0,
T =setInterval(function(){
i < 10 ? $(".test").html(++i) : clearInterval(T);
},1000);
$(".test").html(i);
Try using setInterval() instead:
var i = 0;
var timer = setInterval(function() {
$('.test').html(i);
i++;
if(i > 10) {
clearInterval(timer);
}
}, 10000);
​
Your current loop will loop as fast as it can, and set 10 timeouts to occur in approximately 10 seconds after the loop is called. What setInterval() does is call the code in the function passed to it every 10 seconds, in effect delaying the loop.
The if() statement at the end of it stops the interval occurring if i > 10 by clearing the variable the interval was given a reference to.
I've forked your JSFiddle here, with a 100ms wait time instead of 10s for testing purposes.

Categories