I have a successfully populated array that contain string elements.
And I recently learned about the forEach() of JavaScript
arrayname.forEach(
function(element){
// some statements
}
);
How can I make it work so the "some statements" only run once every three seconds? I tried setInterval and setTimeOut but it did not give me the result I desired. Thanks
I tried this as well
arrayname.forEach( function(element){ }).delay(3000);
but it still did not give me the result I wanted. :(
This function will do it - it's worth avoiding setInterval wherever possible - it has issues where it doesn't guarantee at least delay between calls, particularly if earlier calls have been queued up (perhaps because the window lost focus):
function forEachWithDelay(arr, callback, delay, thisArg) {
var index = 0, count = arr.length;
(function loop() {
if (index < count) {
callback.call(thisArg, arr[index], index, arr); // same as .forEach
++index;
setTimeout(loop, delay);
}
})(); // start the loop immediately
}
usage:
forEachWithDelay(arrayname, function(element, index) {
// do something
}), 3000);
NB: this will start the loop with zero delay for the first element.
var arr = ["Microsoft", "Google", "Apple"];
var i = 0;
function loop() {
alert( arr[i] );
i++;
if( i < arr.length ){
setTimeout( loop, 3000 );
}
};
loop();
This may be what you want:
var i=0;
var loop = setInterval(function(){
if(i < arrayname.length){
console.log(arrayname[i]);
i++;
}else{
clearInterval(loop);
}
},3000);
Here's how you can do it:
var index = 0;
var t = setInterval(function() {
console.log(arrayname[index++]);
if (index === arrayname.length) {
clearInterval(t);
}
}, 3000);
Try this:
$(document).ready(function () {
var array = ["first","second","third","fourth"];
var arr_length = array.length;
var index = 0;
callTime();
function callTime(){
setTimeout(function(){
index++;
if(index < arr_length){
callTime();
}
},1000);
}
});
Related
I want to set timer-based for loop in JavaScript.
for (var i = 0; i < 20; i++) {
console.log(i)
}
How I can I repeat this loop every second and show the value of i (the counter)?
if you want to control your loops wait time you can combine settimeout with recursion
var i = 0;
function callMe() {
var timetowait = 100;
// some condition and more login
i++;
if(i < 20) {
setTimeout(callMe, timetowait);
}
}
callMe();
I think this is what you are looking for:
var counter = 0;
setInterval( function(){
console.log(counter);
counter++;
},1000);
You can try this approach too:
function loop(start, end, delay, fn) {
if (start > end) return;
function step(){
// callback fn with current iteration and
// recursively calls loop
fn(start);
loop(start + 1, end, delay, fn);
}
setTimeout(step, delay);
}
usage :
loop(1, 20, 1000, console.log)
var i = 0;
function myFunc() {
console.log(i);
i++;
if(i == 20) {
clearInterval(interval);
}
}
var interval = setInterval(myFunc, 1000);
The setInterval() method calls a function or evaluates an expression at -
specified intervals (in milliseconds).
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
I want that my for loop should not be executed at once, but wait for timeout after each iteration. For eg :
for(var i=0; i<10; i++) {
console.log(i);
//wait for 1000
}
I found many solutions on stack-overflow like this one :
for (var i=0;i<=10;i++) {
(function(ind) {
setTimeout(function(){console.log(ind);}, 3000);
})(i);
}
But in all the implementations, the loop waits for 3000 milli-seconds initially and then executes the whole for loop at once. Is there a way that each iteration is called after waiting for 1000 milli-seconds.
You can work that out with simple math :
for (var i=0;i<=10;i++) {
(function(ind) {
setTimeout(function(){console.log(ind);}, 1000 + (3000 * ind));
})(i);
}
1000ms : 0
4000ms : 1
7000ms : 2
10000ms : 3
13000ms : 4
...
Following the comments
It seem that your request is a bit blurry. if you want to do something after the last timeout, you can set a limit and compare the current index :
var limit = 10
for (var i=0;i<=limit;i++) {
(function(ind) {
setTimeout(function(){
console.log(ind);
if(ind === limit){
console.log('It was the last one');
}
}, 1000 + (3000 * ind));
})(i);
}
Fiddle : http://jsfiddle.net/Tn4A7/
I think I know what you want...
and it is to simply do
for (var i=0;i<=10;i++) {
(function(ind) {
setTimeout(function(){console.log(ind);}, 1000 * ind);
})(i);
}
Don't make functions within loops, instead:
(function fiveSeconds (n) {
if (n < 5) setTimeout(function () {
fiveSeconds ( n ); // Redo if n < 5 (and pass n)
}, 1000);
console.log( n++ );
} (0)); // Initialize. n is 0
the above will log ten numbers from 0 - 5 at 1 seconds interval.
Modern browsers (and IE10+)
(function fiveSeconds (n) {
console.log( n++ );
if (n <= 5) setTimeout( fiveSeconds, 1000, n ); // Redo if n <= 5 (and pass n)
} (0)); // Initialize. n is 0
why not use something like this:
var i = 0
var id = window.setInterval(function(){
if(i >= 10) {
clearInterval(id);
return;
}
console.log(i);
i++;
}, 1000)
for (var i=0;i<=10;i++) {
(function(ind) {
setTimeout(function(){console.log((ind + 1)*1000, ':', ind);}, 1000 * (ind+1) );
})(i);
}
Output:
1000 : 0
2000 : 1
3000 : 2
4000 : 3
5000 : 4
6000 : 5
7000 : 6
8000 : 7
9000 : 8
10000 : 9
11000 : 10
WORKING DEMO
This works:
function initiateTimeOut(i) {
setTimeout(function() { doStuff(i) }, 30);
}
function doStuff(i) {
console.log(i);
i++;
if (i <= 10) {
initiateTimeOut(i);
}
}
initiateTimeOut(0);
this way you will only increment i when your function executes, which i believe is what your looking for.
Example in a fiddle: http://jsfiddle.net/My7Zg/
Or, even shorter (http://jsfiddle.net/My7Zg/1/):
function customLoop(i) {
console.log(i);
i++;
if (i<=10) {setTimeout(function(){customLoop(i);},1000);}
}
customLoop(0);
Here is an es6 solution. I really don't like wrapping the setTimeout in a function, when you can simply use a block scoped variable like this:
for (let i=0; i<=10; i++) {
setTimeout(() => {console.log(i);}, 1000 * i);
}
You can approach your situation in two ways.
You can immedately schedule a whole bunch of setTimeout() calls with varying times so they will execute at the desired times in the future (other answers here illustrate how to do that).
You can execute the first iteration, schedule the next iteration and have the execution of the next iteration schedule the one after that until you've finished the desired number of iterations. This is ultimately a bit more scalable than setting a lot of setTimeout() call and gives you more branching/logic freedom because you are in control of what happens next after each iteration.
This second option using a more general purpose utility function would look like this:
// utility function to call a callback numTimes,
// separated by delay milliseconds
function runIteration(fn, numTimes, delay) {
var cnt = 0;
function next() {
// call the callback and stop iterating if it returns false
if (fn(cnt) === false) return;
++cnt;
// if not finished with desired number of iterations,
// schedule the next iteration
if (cnt < numTimes) {
setTimeout(next, delay);
}
}
// start first iteration
next();
}
So, to execute your console statement, you'd do this:
runIteration(function(i) {
console.log(i);
}, 10, 1000);
Working demo: http://jsfiddle.net/jfriend00/HqCZ3/
This could also be extended with a 2nd callback function that was called when the iteration was complete (useful in some circumstances) or it could return a promise that is resolved when the iterations are complete.
Here's what a version that returns a promise would look like: http://jsfiddle.net/jfriend00/XtJ69/
// utility function to call a callback numTimes,
// separated by delay milliseconds
function runIteration(fn, numTimes, delay) {
var d = $.Deferred();
var cnt = 0;
function end() {
d.resolve();
}
function next() {
// call the callback and stop iterating if
// it returns false
if (fn(cnt) === false) {
end();
return;
}
++cnt;
// if not finished with desired number of iterations,
// schedule the next iteration
if (cnt < numTimes) {
setTimeout(next, delay);
} else {
end();
}
}
// start first iteration
next();
return d.promise();
}
runIteration(function(i) {
log(i);
}, 10, 1000).done(function() {
log("done");
});
Another workaround is to use a generator function with setInterval:
const steps = function*() {
for (let i=0; i<10; i++) {
yield i;
}
}
const step = steps();
setInterval(function(){
console.log(step.next().value)
}, 1000);
This is a solution with a simple timeout... Maybe it does not match exactly with what you expect, but trying to make a "pause" with javascript is not a good approach in my advice. I suggest you to search an other way to do what you want. Fiddle
window.my_condition = true;
window.my_i = 0;
function interate() {
console.log(window.my_i);
// ... your code
if (window.my_condition!==false) {
window.my_i++;
setTimeout(interate,300);
}
}
interate();
most of the answers in here are completely wrong.
If you want to wait for each iteration to finish --- then you don't want to use a for loop --- simply the wrong strategy to begin with.
you need to use a counter and a counter limit otherwise it will loop endlessly.
here is the solution:
var optionLimit = 11;
var optionItem = 1;
function do_something_else() {
if (optionItem < optionLimit) {
console.log('doing stuff:' + optionItem)
optionItem++
dostuff();
} else {
console.log('no more stuff to do already reached:' + optionItem)
}
}
function dostuff(started) {
if (started) {
console.log('started doing something');
} else {
console.log('find something else to do');
}
setTimeout(function () {
do_something_else();
}, 3000);
}
dostuff('started doing something');
if you have a set of items that you need to index --- then you can use a loop to count through the number of items that need to be executed like so:
var thingstodo = [
thing1 = {
what: 'clean room',
time: 8000
},
thing2 = {
what: 'laundry',
time: 9000
},
thing3 = {
what: 'take out trash',
time: 6000
},
thing4 = {
what: 'wash dishes',
time: 10000
}
]
var optionLimit = 0;
// find how many things to do from things to do list
function get_things_todo(time) {
console.log('heres stuff i can do');
console.log('====================');
for (var i = 0; i < thingstodo.length; i++) {
val = thingstodo[i];
console.log(JSON.stringify(val.what));
optionLimit++
}
setTimeout(function () {
startdostuff(3000)
}, time);
}
var optionItem = 0;
// find the next thing to do on the list
function get_next_thing(time) {
setTimeout(function () {
console.log('================================');
console.log('let me find the next thing to do');
}, time);
setTimeout(function () {
if (optionItem < optionLimit) {
val = thingstodo[optionItem];
dostuff(3000, val);
optionItem++
} else {
console.log('=====================================================');
console.log('no more stuff to do i finished everything on the list')
}
}, time*1.5);
}
//do stuff with a 3000ms delay
function dostuff(ftime, val) {
setTimeout(function () {
console.log('================================');
console.log('im gonna ' + JSON.stringify(val.what));
console.log('will finish in: ' + JSON.stringify(val.time) + ' milliseconds');
setTimeout(function () {
console.log('========');
console.log('all done');
get_next_thing(3000);
}, val.time);
}, ftime);
}
//start doing stuff
function startdostuff(time) {
console.log('========================');
console.log('just started doing stuff');
setTimeout(function () {
get_next_thing(3000);
}, time);
}
/// get things to first
get_things_todo(3000);
My best way in work is to "forget normal loops" in this case and use this combination of "setInterval" includes "setTimeOut"s:
function iAsk(lvl){
var i=0;
var intr =setInterval(function(){ // start the loop
i++; // increment it
if(i>lvl){ // check if the end round reached.
clearInterval(intr);
return;
}
setTimeout(function(){
$(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond
},50);
setTimeout(function(){
// do another bla bla bla after 100 millisecond.
seq[i-1]=(Math.ceil(Math.random()*4)).toString();
$("#hh").after('<br>'+i + ' : rand= '+(Math.ceil(Math.random()*4)).toString()+' > '+seq[i-1]);
$("#d"+seq[i-1]).prop("src",pGif);
var d =document.getElementById('aud');
d.play();
},100);
setTimeout(function(){
// keep adding bla bla bla till you done :)
$("#d"+seq[i-1]).prop("src",pPng);
},900);
},1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions)
}
PS: Understand that the real behavior of (setTimeOut): they all will start in same time "the three bla bla bla will start counting down in the same moment" so make a different timeout to arrange the execution.
PS 2: the example for timing loop, but for a reaction loops you can use events, promise async await ..
I share a simple solution to do this.
To solve this problem, you need to use closure: immediately invoke the function that will be called on each iteration with "i" as param and setTimeout inside this function. In this case, the parameter you passed will be stored in scope and could be used in the timeout callback:
for (var i=1; i<6; i++) (function(t) {
setTimeout(function() {
//do anything with t
}, t*1000)
}(i))
With this example you would see approximately what happens with the function:
for (var i=1; i<6; i++) (function(t) {
setTimeout(function() {
console.log(t);
}, t*1000)
}(i))
This is the answer!
Less code, easy to integrate.
for (let i = 1; i < 10 ; i++){
var time = i * 1000
setTimeout(function(){console.log("re" + i);}, time)
}
Since node 7.6, you can use a handy promisify method that makes sleeping a one liner.
CommonJS:
const sleep = require('util').promisify(setTimeout);
ESM:
import { promisify } from "util";
const sleep = promisify(setTimeout);
In your code:
;(async function() {
for(var i = 0; i < 10; i++) {
console.log(i);
await sleep(10000);
}
})();
I am trying to loop over an array. However, I would like to add a 15 second delay between each array value. This will write value 1 to console, then count down 15 seconds and write value 2 to console, and so on.
I'm not sure exactly how to do this. My code as of now just outputs the numbers 15 all the way to 1 on the console at once with no actual count down and no array values.
array
["l3", "l4", "l5", "l6", "l7", "l8", "l9", "l10", "l11", "l12", "l13", "l14", "l15", "l16"]
code
var adArray = [];
// get links with class adfu
var adfuClass = document.getElementsByClassName('adfu');
for (var i = 0; i < adfuClass.length; i++) {
var ids = adfuClass[i].id
var newIds = ids.replace(/tg_/i, "l");
adArray.push(newIds);
}
// get links with class ad30
var ad30Class = document.getElementsByClassName('ad30');
for (var i = 0; i < ad30Class.length; i++) {
var ids = ad30Class[i].id;
var newIds = ids.replace(/tg_/i, "l");
adArray.push(newIds);
}
// get links with class adf
var adfClass = document.getElementsByClassName('adf');
for (var i = 0; i < adfClass.length; i++) {
var ids = adfClass[i].id;
var newIds = ids.replace(/tg_/i, "l");
adArray.push(newIds);
}
// loop through array with all new ids
for (var i = 0, l = adArray.length; i < l; i++) {
var counter = 15;
var countDown = setTimeout(function() {
console.log(counter);
if (counter == 0) {
console.log(adArray[i]);
}
counter--;
}, 1000);
}
// loop through array with all new ids
var i = 0, l = adArray.length;
(function iterator() {
console.log(adArray[i]);
if(++i<l) {
setTimeout(iterator, 15000);
}
})();
Something like this?
There's a really simple pattern for this type of iterator, using closure scope to store a loop counter and a nested looper() function which runs the setTimeout() iterator. The looper() function actually iterates the loop count, so there is no need for a for or do/while construct. I use this pattern often, and it works really well.
EDIT: Modified the condition to check for loop > 1, not loop > 0, which logged Loop count: 0. This can be tweaked, and technically, the looper() here runs 16 times.
(function(){
var loop = 15;
var looper = function(){
console.log('Loop count: ' + loop);
if (loop > 1) {
loop--;
} else {
console.log('Loop end.');
return;
}
setTimeout(looper, 15000);
};
looper();
})();
http://jsfiddle.net/userdude/NV7HU/2
Use this function to make it easier to run:
function loopArr(arr, callback, time, infinite){
console.log('loop run');
var i=0,
total=arr.length-1;
var loop=function(){
// RUN CODE
console.log('loop arr['+i+']');
callback( arr[i] );
if (i < total ) {
i++;
} else { // LOOP END
console.log('loop end!');
if(!infinite) return;
i=0 //restart
}
setTimeout( loop, time);
}
loop()
}
To use this function execute this:
loopArr(arr, callback, time, infinite)
Where:
arr is the array we need to loop, it could be a jQuery selector
callback is the executed function with one argument returned which is the selected item
time is the timeout needed for delay
infinite is set true or false if we need the code to repeat itself forever
Example using animate.css :
var imgShowHide = function(elm){
var elm = $(elm); // select the item arr[i] via jQuery
elm.css('animation-duration','2s').show()
.addClass('animated bounceInRight')
.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
elm.removeClass('animated bounceInRight')
.addClass('animated bounceInLeft')
.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
elm.removeClass('animated bounceInLeft').hide()
})
});
}
// RUN
loopArr( $('#images > img'), imgShowHide, 4000, true);
I want to pause 1 second for every time it loops, it is usually easy to do similar pauses on other cases, but when working with loops, it seems it get harder:
for (var i=0 ; i < 10 ; i++) {
document.write (i + "<br>");
// I want to wait 1 second here
}
This is one example of my thousands failed attempts:
function writeMsg (index) {
document.write (index + "<br>");
}
for (var i=0 ; i < 10 ; i++) {
setTimeout (writeMsg(i), 1000);
}
Any ideas of how to get this to work?
This function works more like a normal for loop while it isn't
You need to take into account that a for gets 3 arguments inbetween semicolons.
Before starting (ie var i=0 you define a variable)
A condition before running the code again (ie i < 10 while i is under 10)
An action everytime it finishes the code again (i++ add one to i)
Code
(function() {
// Define a variable
var i = 0,
action = function() {
// Condition to run again
if (i < 10) {
document.write(i + "<br>");
// Add one to i
i++;
setTimeout(action, 1000);
}
};
setTimeout(action, 1000);
})();
Here is a jsfiddle for this code demonstrating its working:
http://jsfiddle.net/sg3s/n9BNQ/
You pass the return value of a function call to setTimeout instead of a function. Try the following code:
for (var i = 0; i < 10; i++) {
(function(i) {
setTimeout(function() {
writeMsg(i);
}, 1000*i);
})(i);
}
In case you wonder why the call is wrapped inside an anonymous function: Without that function each setTimeout callback would receive the same i so when the callbacks fire it would always be 10. The anonymous function creates a new i inside that is not connected to the loop variable.
Classic function-in-a-loop problem. One archetypal solution:
function createCallback(i) {
return function () {
writeMsg(i);
};
}
function writeMsg (index) {
document.write (index + "<br>");
}
for (var i=0 ; i < 10 ; i++) {
setTimeout (createCallback(i), 1000*i);
}
The 10 timeouts are all based on the time that setTimeout() is called. So, they are all triggered at the same time.
for (var i=0; i < 10; i++) {
(function(idx){
setTimeout(function(){
document.write(idx+"<br/>");
},1000*idx);
})(i);
};
try this it will definitely help who all are think how to make it work wait property inside For Loop...
try this code in this URL http://www.shopjustice.com/the-collections/C-10329.
var var2;
var tmp;
var evt;
var i=0;
var res = document.getElementsByClassName('mar-plp-filter-content nav nav--stacked')[0].children.length;
tmp = document.getElementsByClassName('mar-plp-filter-content nav nav--stacked')[0].children;
function myfunc()
{
if(i<res)
{
var2 = tmp[i].getElementsByTagName("span")[0].getElementsByClassName("inverted")[0];
// alert(var2.innerHTML);
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( 'mouseover', true, false );
var2.dispatchEvent(evObj);
var2.style.backgroundColor="GREEN";
i++;
setTimeout(myfunc,3000);
}
};
setTimeout(myfunc,3000);
I am trying to create a page which needs to preform lots of loops. Using a while/for loops cause the page to hang until the loop completes and it is possible in this case that the loop could be running for hours. I have also tried using setTimeout, but that hits a recursion limit. How do I prevent the page from reaching a recursion limit?
var looper = {
characters: 'abcdefghijklmnopqrstuvwxyz',
current: [0],
target: '',
max: 25,
setHash: function(hash) {
this.target = hash;
this.max = this.characters.length;
},
getString: function() {
string = '';
for (letter in this.current) {
string += this.characters[this.current[letter]];
}
return string;
},
hash: function() {
return Sha1.hash(this.getString());
},
increment: function() {
this.current[0] += 1;
if (this.current[0] > this.max) {
if (this.current.length == 1) {
this.current = [0, 0];
} else {
this.current[1] += 1;
this.current[0] = 0;
}
}
if (this.current[1] > this.max) {
if (this.current.length == 2) {
this.current[2] == 0;
} else {
this.current[3] += 1;
this.current[2] = 0;
}
}
},
loop: function() {
if (this.hash() == this.target) {
alert(this.getString());
} else {
this.increment();
setTimeout(this.loop(), 1);
}
}
}
setInterval is the usual way, but you could also try web workers, which would be a more straightforward refactoring of your code than setInterval but would only work on HTML5 browsers.
http://dev.w3.org/html5/workers/
Your setTimeout is not doing what you think it's doing. Here's what it's doing:
It encounters this statement:
setTimeout(this.loop(), 1);
It evaluates the first argument to setTimeout, this.loop(). It calls loop right there; it does not wait for a millisecond as you likely expected.
It calls setTimeout like this:
setTimeout(undefined, 1);
In theory, anyway. In reality, the second step never completes; it recurses indefinitely. What you need to do is pass a reference to the function rather than the returned value of the function:
setTimeout(this.loop, 1);
However, then this will be window on the next loop, not looper. Bind it, instead:
setTimeout(this.loop.bind(this), 1);
setInterval might work. It calls a function every certain amount of milliseconds.
For Example
myInterval = setInterval(myFunction,5000);
That will call your function (myFunction) every 5 seconds.
why not have a loop checker using setInterval?
var loopWorking = false;
function looper(){
loopWorking = true;
//Do stuff
loopWorking = false;
}
function checkLooper()
{
if(loopWorking == false)
looper();
}
setInterval(checkLooper, 100); //every 100ms or lower. Can reduce down to 1ms
If you want to avoid recursion then don't call this.loop() from inside of this.loop(). Instead use window.setInterval() to call the loop repeatedly.
I had to hand-code continuation passing style in google-code prettify.
Basically I turned
for (var i = 0, n = arr.length; i < n; ++i) {
processItem(i);
}
done();
into
var i = 0, n = arr.length;
function work() {
var t0 = +new Date;
while (i < n) {
processItem(i);
++i;
if (new Date - t0 > 100) {
setTimeout(work, 250);
return;
}
}
done();
}
work();
which doesn't hit any recursion limit since there are no recursive function calls.