D
D
Danil2016-02-02 14:05:22
MySQL
Danil, 2016-02-02 14:05:22

Why is the value of the variable not visible?

There is this code:

for (var i=0; i<vendors.length; i++) {
    console.log(i)
    connection.query('SELECT * FROM `brends` WHERE `brend_parrent`="'+vendors[і].id_folders+'";', function(err, rows, fields) {
        if (err) throw err;
        console.log(i)
   })
}

The first console log displays i correctly, the 2nd one always displays the maximum value. Why is that? And yes, perhaps there is a better way than doing a selection from the database in a loop?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Artem Shchurin, 2016-02-02
@Veneomin

All callbacks that you pass to the query method are queued for execution, during this time the cycle has time to work out to the end and when we take the iterator value in the callback, we get the value by reference, in which the iterator has already been increased to the maximum, the output is:
1. Pass the iterator to callback for each request --> (err, rows, fields, i)
2. Use forEach

[0,1,2,3].forEach(function(item, index){
  setTimeout(function(){
    console.log(index)
  }, 0)
})

H
HoHsi, 2016-02-07
@HoHsi

This is called IIFE. Since the query to the database is asynchronous, and for is synchronous, it processes faster, preserving the internal value of i on the final iteration. This means that you need to close for each call to i in order for it to become local. This is a problem with var variables, since they have the scope of the entire function, not a block. This can be solved:

for (var i=0, len = vendors.length; i < len ; i++) {
    (function (i) {
        console.log(i);
        connection.query('SELECT * FROM `brends` WHERE `brend_parrent`="'+vendors[і].id_folders+'";', function(err, rows, fields) {
            if (err) throw err;
            console.log(i);
        });
    })(i);
}

for (let i=0, len = vendors.length; i < len ; i++) {
    console.log(i);
    connection.query('SELECT * FROM `brends` WHERE `brend_parrent`="'+vendors[і].id_folders+'";', function(err, rows, fields) {
        if (err) throw err;
        console.log(i);
   });
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question