Understanding asynchronous callbacks [duplicate] - javascript

This question already has answers here:
setTimeout in for-loop does not print consecutive values [duplicate]
(10 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 years ago.
I'm new to asynchronous programming, and I'm having a hard time getting the concept.
Please help!!!
Ive come up with a simple example:
for (var i = 1; i <= 10; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
All I want is to print the indexes in ascending order but due to asynchronous action forced by the setTimeout i'm getting the last index printed out 10 times.
I understand why this happens...
No matter what I've tried (I don't think my misunderstanding needs elaboration) I failed solving this stupid riddle...
Im obviously missing something basic.
Please help me figure it out.

It's because all those functions use the same variable i, which is equal to 10 during invocation of them. Try something like this:
for (var i = 1; i <= 10; i++) {
setTimeout((function (k) {
return function(){
console.log(k);
}
}(i)), 1000);
}
It's because JavaScript has closures. You can read about them here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

Related

Unclear behavior of While loop [duplicate]

This question already has answers here:
Javascript while loop return value
(3 answers)
Closed 2 years ago.
As someone new to js, I was playing with loops when I encountered some peculiar behavior with the following code:
var i = 5;
while(i!=0){
console.log(i);
i--;
}
OUTPUT: 543211
I replicated the same code in c++ :
int i = 5;
while(i!=0){
cout<<i;
i--;
}
OUTPUT: 54321
It'd help to know if I'm missing some important differences between the two languages.
If you run the code in the browser console, whatever the last statement evaluates to will log to the console as well. It's not actually getting console.log'd, though.
For example, if you do this:
var i = 5;
while(i!=0){
console.log(i);
i--;
'';
}
At the end of your list you will see ''

Functions Considered as Objects in JavaScript [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 2 years ago.
I am new to JavaScript (and StackOverflow) and am hoping to get some help on a problem that has bothered me for some time. I understand that functions are considered objects in JS. A function is different from an object in the sense that it can execute code.
This may be a very simple and straightforward question to some of you veteran folks. I don't understand how the code works below. Essentially there is a function count() that returns an anonymous counter function. keepCount points to the anonymous function (an object, of course) that count() returns.
function count() {
var num = 0;
return function(correct) {
if (correct)
num++;
return num;
}
}
var keepCount = count();
keepCount(true); // num is 1
keepCount(true); // num is 2
keepCount(true); // 3
keepCount(true); // 4
console.log(keepCount(true)); // Call it again and print. It is 5.
My question: What is causing the result of num to be 'saved' or recorded with each function call? Isn't num a variable local to count() — the outer function? num does not appear to be a property of the anonymous function. I suspect the answer has something to do with the fact that functions are considered objects in JS, and that a local variable can be continuously updated in the variable object of count(). A new variable object is not produced for count() with each call of the anonymous function.
I would also appreciate comments on the formatting of this question and all. I want to be sure that I am following StackOverflow guidelines properly. I also hope that the details of the question make sense. Please let me know if anyone requires clarification.

using setTimeout with var and let - different results [duplicate]

This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
Closed 5 years ago.
Why the following code returns 10 times 10 and print hey as first line?
for (var i = 0; i < 10; ++i) {
setTimeout(() => console.log(i), 0)
}
console.log('hey')
When if instead I use let I get properly the counting, but why the line hey is always printed first?
for (let i = 0; i < 10; ++i) {
setTimeout(() => console.log(i), 0)
}
console.log('hey')
My question actually contains two:
First why hey is printed first.
Why using let the counting is printed properly.
setTimeout() is an asynchronous function
console.log('hey')
won't wait for it to finish before printing, since JS is single threaded, it would wait for the program to run and then pick the setTimeout() from event queue
difference between let and var can be found in this answer. Basically since let has scope limited to the for loop, the setTimeout can refer to only 1 value of i. If we use var then it is function scope and each function would get the same value of i

How to bind your variables to setTimeout in javascript? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
for(i = 0; i < 10; i++){
setTimeOut(function(){
console.log(i);
},2000);
}
When I execute this, its printing 10, 10 times instead of 1,2,3....10. How do I fix this
You need to modify your code like this
function print(i){
console.log(i);
}
for(i=0;i<10;i++){
setTimeout(print.bind(null,i),2000);
}

Using getJSON in for loop, why do I have to assign a function to hold the value of counter? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
Here is the code somebody else posted as a solution:
for (var i = 0; i < array.length; i++) {
(function(i) { // protects i in an immediately called function
$.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
$('#' + array[i]).text(data.query.querypage.results.length);
});
})(i);
}
Specifically, what does the (i) do at the end of the function?
The short answer is, if you don't, the value of i will not be as you expect it to be for later function calls. Removing the closure (the (i)) will make it always the maximum value for all calls, as they all happen instantaneously (such is the nature of asynchronous programming).
You create a function around this call, then call that function with the value of i that you want to preserve the value for when the getJSON finishes. Note also, if you were using ES2015, you could use for(let i = 0; ...) and it would handle the scoping for you.

Categories