Reputation: 73
Can someone explain to me what is happening to the for
loop here? I don't understand why the loop goes beyond its' condition. I expect condition [i]
to stop at '2'. I suppose that this behavior would be same for other async functions inside a for
loop. Much thanks!
var path = require('path')
var fs = require('fs')
var request = require('request')
var cheerio = require('cheerio')
for (i=0; i < 3; i++) {
console.log(i)
var arr = []
var url = 'https://en.wikipedia.org/wiki/Web_scraping'
request (url, function(error,response,body) {
if(error){
throw err;
} $ = cheerio.load(body)
var x = $.html()
console.log(i)
})
}
/* Results
0
1
2
3
3
3
*/
Upvotes: 1
Views: 154
Reputation: 105449
Your loop executes exactly 3 times and logs i
here - 0,1,2
:
for(i=0; i < 3; i++){
console.log(i)
^^^^^^^^^^^^^ <--------------------------------
But then callback that is added here
request(url, function(error,response,body){
^^^^^^^^^^^^ <----------------------------
is executed 3 times and logs 3, 3, 3
:
if(error){
throw err;
} $ = cheerio.load(body)
var x = $.html()
console.log(i)
^^^^^^^^^^^^^ <-----------------------------
})
See this question to understand why i
is outputted as 3
in the callback three times, instead of 0, 1, 2
as you'd probably expect. If you used let
instead of var
, you'd get expected 0, 1, 2
:
for(let i=0; i < 3; i++){
Upvotes: 2
Reputation: 8584
Maximus tells you why the code is doing what it does. But how do you fix it? The most basic way, if you can use ES6 language features (which you probably can, since it looks like you're using Node.js), is to declare your variables with let
instead of var
. let
behaves in a way that you would probably expect. In addition to behaving more reasonably when referenced from lambdas, variables declared with let
are block scoped instead of function scoped, which is more intuitive.
Upvotes: 1