how to get exact value in setTimeout function [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
javascript using settimeout() with a loop
(4 answers)
Closed 9 years ago.
Simple question...
for (var i = 0; i < 5; i++) {
setTimeout(function () { alert(i) }, 3000);
}
how to alert 5 times with exact value of i.
It gives "5" only 5 times.
I need its result like
0
1
2
3
4

With a closure that keeps the value of the variable constant within the new scope of the immediately invoked function
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(function () { alert(j) }, 3000);
}(i));
}
The setTimout is asynchronous, so by the time it executes the loop has long since completed, and the value of i has been changed to 5, so you need to lock it in.

You can use setInterval alternate to setTimeout
Try,
var xCnt = 0;
var xInterval = setInterval(function()
{
xCnt +=1;
alert(xCnt);
if(xCnt == 5)
{
clearInterval(xInterval);
}
}, 3000);
DEMO

Related

how to create dynamic function in javascript with for loop and its index inside function [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
var data = ["s","a"]
var asyncFunctionss = [];
for (var i in data) {
asyncFunctionss.push(function (callback) {
console.log(i);
});
}
for (var g in asyncFunctionss) {
asyncFunctionss[g]();
}
I try to run this program it give the following output.
Expected Output
0
1
Actual Output
1
1
How to achieve the Expected output ?
You need an IIFE. The reason is that as soon as a function element in asyncFunctionss is called the variable i is already 1. You could use a IIFE to remember the value of variable i:
var data = ["s","a"]
var asyncFunctionss = [];
for (var i in data) {
(function(i){
asyncFunctionss.push(function (callback) {
console.log(i);
});
})(i);
}
for (var g in asyncFunctionss) {
asyncFunctionss[g]();
}

Javascript iterator design pattern [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
How do JavaScript closures work?
(86 answers)
Closed 7 years ago.
I am confused why the following code snippet has (i) at the end of it:
for (var i = 0; i < 10; i += 1) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
Ive seen it in production code Ive worked on--I just can intuit why it's necessary.
You are defining an inline function, so you could force the i parameter to be in the local scope at the time of the execution of the console.log statement. By adding the parameter, you are creating a self executing function. Similar would be the following statements, which might be better to read...
function logmeWithTimeOut(value) {
setTimeout(function() { console.log(value); }, 1000);
}
for (var i = 0; i < 10; i++) {
logmeWithTimeout(i);
}
Though I might prefer
function logmeWithTimeout(value) {
console.log(value);
}
for (var i = 0; i < 10; i++) {
setTimeout(logmeWithTimeout.bind(undefined, i), 1000);
}
It forces the i to be in local scope, otherwise your log would print only 11
Because you are defining a function inside the parenthesis, and then you are calling it passing i as parameter.
If you didn't put the (i) there, you would just define a function but never call it.

delay a for loop with javascript [duplicate]

This question already has answers here:
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 8 years ago.
I want to delay a "for loop" for a while but don't know how to do it.
For example. Let's say this "for loop" runs from 0 to 8 and after each i there should be a delay for 2 sek.
for (var i=0; i<8; i++{
do something...
wait for 2 sek. and go on with i=i++;
}
You'll have to go that way:
function jsHello(i) {
if (i < 0) return;
setTimeout(function () {
alert("Hello " + i);
jsHello(--i);
}, 2000);
}
jsHello(5);
or
function jsHello(i) {
alert("Hello " + i);
if (--i > -1) {
setTimeout(function () { jsHello(i); }, 2000);
}
}
jsHello(5);
Javascript doesn't have a wait command. The way to get this behavior is using setTimeout:
for (var i=0; i<8; i++){
do_something(i);
}
function do_something(j) {
setTimeout(function() {
tasks to do;
}, 2000 * j);
}
Every time the function do_something() is called, it executes "tasks to do" scheduled by 2000*i milliseconds.
To resolve this task you have to use closure - immediately invoke function witch be called on every iteration with i as param, and setTimeout inside this function. In this case param you passed will be stored in scope and could be used in timeout callback:
for (var i=0; i<8; i++) (function(t) {
window.setTimeout(function() {
//do anything with t
}, t*2000)
}(i))
UPD
Also here is a shorten ES6 version. As let has block scope you can get rid os wrap function closure use
for (let i=0; i<8; i++){
setTimeout(() => {
console.log(i)
}, 2000 * i);
}

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);

Javascript closures for iterated function definitions [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript closure?
This has probably been asked before, but...
If I want a list of functions
var funs = [
function(){ console.log(1); },
function(){ console.log(2); },
function(){ console.log(3); },
function(){ console.log(4); },
function(){ console.log(5); } ]
it would seem that one could make it by something like:
var funs = [];
for(var i=1; i <= 5; i++){
funs.push(function(){ console.log(i) };
}
Which doesn't work, as the variable i is a single variable bound to all the functions, so that
funs[0](); funs[1](); funs[2](); funs[3](); funs[4]();
outputs
6
6
6
6
6
not
1
2
3
4
5
This isn't the output I want. I guess I need to force javascript to bind a copy of the value of i at the time the function is created, instead of closing with the reference for i. How would I do this?
The easiest way is passing the function through the argument of a self-executing function:
for(...) {
(function(i) {
// here you have a new i in every loop
})(i);
}

Categories

Resources