2016-12-01 6 views
0

Ich benutze Knoten mit Mysql und hier ist mein Problem.führen async mehrere Mysql-Abfragen auf Knoten

ich neue Fotos auf meiner Datenbank hinzuzufügen bin versucht, und senden Sie es als ein Array

hier ist meine Funktion:

function addNewPhotos(_id, files) { 
var deferred = Q.defer(); 
var new_photos = [] 
_.each(files, function (one) { 
    var data = [ 
     one.path, 
     _id, 
     0 
    ] 
    var sql = 'INSERT INTO photos(photo_link, id_user, isProfil) VALUES (?, ?, ?)'; 
    db.connection.query(sql, data, function (err, result) { 

     if (err) 
      deferred.reject(err.name + ': ' + err.message); 
     var sql = 'SELECT id_user, photo_link, isProfil FROM `photos` WHERE id = ?'; 
     if (result){ 
      db.connection.query(sql, [result.insertId], function(err, photo) { 
       if (err) deferred.reject(err.name + ': ' + err.message); 
       if (photo) { 
        new_photos.push(photo[0]); 
       } 
      }); 
     } 
    }) 
}) 
deferred.resolve(Array.prototype.slice.call(new_photos)); 
return deferred.promise} 

Das Einfügen funktioniert gut, aber ich die Ergebnisse nicht abrufen kann Sende sie zurück an den Kunden. (mein Array ist leer)

Danke.

+0

'db.connection.query' ist asynchron, so dass alles außerhalb seines Callbacks stattfindet, bevor der Callback aufgerufen wird. –

Antwort

2

auf der untersten Ebene promisify, in diesem Fall db.connection.query().

if(!db.connection.queryAsync) { 
    db.connection.queryAsync = function(sql, data) { 
     return Q.Promise(function(resolve, reject) { // or possibly Q.promise (with lower case p), depending on version 
      db.connection.query(sql, data, function(err, result) { 
       if(err) { 
        reject(err); 
       } else { 
        resolve(result); 
       } 
      }); 
     }); 
    }; 
} 

Jetzt ist der Code höherer Ebene wird sehr einfach:

function addNewPhotos(_id, files) { 
    var sql_1 = 'INSERT INTO photos(photo_link, id_user, isProfil) VALUES (?, ?, ?)', 
     sql_2 = 'SELECT id_user, photo_link, isProfil FROM `photos` WHERE id = ?'; 
    return Q.all(files.map(function(one) { 
     return db.connection.queryAsync(sql_1, [one.path, _id, 0]).then(function(result) { 
      return db.connection.queryAsync(sql_2, [result.insertId]); 
     }); 
    })); 
}; 

Um einen einzigen Ausfall zu verhindern, dass die ganze Sache zum Scheitern könnte wählen Sie individuelle Fehler zu fangen und eine Art von Standard zu injizieren;

function addNewPhotos(_id, files) { 
    var sql_1 = 'INSERT INTO photos(photo_link, id_user, isProfil) VALUES (?, ?, ?)', 
     sql_2 = 'SELECT id_user, photo_link, isProfil FROM `photos` WHERE id = ?', 
     defaultPhoto = /* whatever you want as a default string/object in case of error */; 
    return Q.all(files.map(function(one) { 
     return db.connection.queryAsync(sql_1, [one.path, _id, 0]).then(function(result) { 
      return db.connection.queryAsync(sql_2, [result.insertId]); 
     }).catch(function() { 
      return defaultPhoto; 
     }); 
    })); 
}; 
+0

Vielen Dank, ich bin neuer auf async Anruf, ich dachte den Prozess anders! –

+0

Einige Fehlerkorrekturen hinzugefügt, die Sie möglicherweise nützlich finden. –

-1

Sie die Rückkehr in Ihrer Funktion Asynchron-Schleife, wenn alle immer getan wurde

function addNewPhotos(_id, files) { 
var deferred = Q.defer(); 
var new_photos = []; 

var todo = files.length; 
var done = 0; 
_.each(files, function (one) { 
    var data = [ 
     one.path, 
     _id, 
     0 
    ] 
    var sql = 'INSERT INTO photos(photo_link, id_user, isProfil) VALUES (?, ?, ?)'; 
    db.connection.query(sql, data, function (err, result) { 

     if (err) 
      deferred.reject(err.name + ': ' + err.message); 
     var sql = 'SELECT id_user, photo_link, isProfil FROM `photos` WHERE id = ?'; 
     if (result){ 
      db.connection.query(sql, [result.insertId], function(err, photo) { 
       if (err) deferred.reject(err.name + ': ' + err.message); 
       if (photo) { 
        new_photos.push(photo[0]); 
       } 
       if(++done >= todo){ 
        deferred.resolve(Array.prototype.slice.call(new_photos)); 
        return deferred.promise 
       } 
      }); 
     } 
     else 
     { 
      if(++done >= todo){ 
       deferred.resolve(Array.prototype.slice.call(new_photos)); 
       return deferred.promise; 
      } 
     } 
    }) 
    }) 
}