2015-03-22 1 views
0
var std; 
...... 
...... // here I fill std with some data 
...... 

Я пытаюсь получить доступ к «» зОго массива при обращении по этому маршруту:NodeJS сфера выпуск

app.post('/saveABS',function(req,res){ 
var fileName = "./public/"+f; 
fs.writeFile(fileName, JSON.stringify(std, null, 4), function(err) { 
    if(err) { 
     console.log(err); 
    } else { 
     console.log("The file was saved !"); 
     console.log(a); 
     for(var i = 0; i < std.length; i++) 
     { 
      var connection = mysql.createConnection({ 
       host  : 'localhost', 
       user  : 'root', 
       password : 'admin' , 
       database : 'pfe' 
      }); 
      console.log('before hr_cours = ' + std[i].hr_cours); // <========= WORKS 

Здесь отображается значение станда [я] .hr_cours правильно.

  if(std[i].hr_cours != a[i].hr_cours) 
      { 

       connection.connect(function(error){ 
        console.log('after hr_cours = ' + std[i].hr_cours); // <============ undefined 

Здесь он отображается неопределенный.

    if(error) 
        { 
         console.log('Unable to connect to database.'); 
        } 
        else 
        { 
         console.log("i= " + i); 
         console.log("I'm in : hr_cours = " + std[i].hr_cours); 
         connection.query("INSERT INTO assiste VALUES (CURDATE(),(SELECT id_etud FROM Etudiant WHERE nom_etud = ?),(SELECT s.id_seanceFROM Seance s, aura_lieu a, jour j, fait_objet fWHERE s.id_seance = a.id_seanceAND CURTIME() BETWEEN a.heure_debut AND a.heure_fin AND a.id_jour = j.id_jour AND j.dat = CURDATE() AND f.id_seance = s.id_seance AND f.id_ens = ?), ?)", [std[i].nom_etud, idEns, std[i].hr_cours], function(er1, res1){ 
          if(er1) 
          { 
           console.log('Query error: '); 
          } 
          else 
          { 
           console.log('success'); 
          } 
         }); 
        } 
       }); 
      } 
     } 
     res.end("all"); 
    } 
}); 
}); 

Я заметил, что вопрос срабатывает после того, как поток выполнения переходит в блок connection.connect и что это вопрос сферы; Я искал всюду для ответа, но не смог найти решение моей конкретной проблемы. Как я могу сделать эту работу?

+0

Вы можете подумать о запуске узла с помощью '-harmony' и использовать« let »вместо« var »: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let – FoggyDay

+0

I сделал ... но такой же старая ошибка –

+1

возможный дубликат [JavaScript закрытия внутри петель - простой практический пример] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

ответ

1

Выполнение connection.connect задерживается, и поэтому, когда он запускает i не то же самое значение, что, когда ссылка на i был принят в него петлей for. Таким образом, чтобы зафиксировать значения i в этом конкретном выполнении цикла, перенесите метод connection.connect и обратный вызов в IIFE и передать i, как это параметр:

~function(i) { 
    connection.connect(function(error){ 
     console.log('after hr_cours = ' + std[i].hr_cours); 
     // other stuff 
    }) 
}(i) 

Более подробное объяснение IIFE-х и закрытие сферы в моем ответе здесь: Odd javascript code execution order

И игровая площадка JSFiddle для изучения техники: IIFE Scope Closure With Pre-Existing Parameters.

+0

Благодарим вас за драгоценную помощь! –

1

Вот ваша проблема:

app.post('/saveABS', function(req, res) { 
    // ... 
    for (var i = 0; i < std.length; i++) {     
     // ... 
     // This is SYNC. Here i = 0,1,2... 
     connection.connect(function(error) { 
      // This is A-SYNC. 
      // Here i = std.length + 1 
      // always! 
      // No matter even if it syntactically looks like i should be 1,2,3 according to the loop 
      // but all of this is executed way after the loop has long been completed 

      // ... 
      // Here it displays undefined. 
      console.log('after hr_cours = ' + std[i].hr_cours); // <============ undefined 

Решение: Есть сам исполняющий анонимную функцию (function(){})() внутри цикла и передать его аргументы (i), так что они будут оставаться один и тот же

for (var i = 0; i < std.length; i++) (function(i){ 
    connection.connect(function(error) { 
     // ... 
     // Here, since i is an argument passed to outer function 
     // i will be i,2,3... 
})(i); 

Другое решение: петля forEach, которая уже имеет функцию обратного вызова

std.forEach(function(currentValue, i, std){ 
    connection.connect(function(error) { 
     // ... 
     // Same here, since i is an argument passed to outer function 
     // i will be i,2,3...  
     // Also currentValue = std[i] so you can use that 
}); 
+0

спасибо большое! работал как шарм! –

Смежные вопросы