2016-12-01 14 views
0

Я использую узел с Mysql, и вот моя проблема.выполнить async несколько запросов Mysql на узле

Я пытаюсь добавить новые фотографии в моей базе данных и вернуть его как массив

вот моя функция:

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} 

Вставка работает хорошо, но я не могу получить результаты в отправьте их клиенту. (мой массив пуст)

Спасибо.

+0

'db.connection.query' является асинхронным, поэтому перед вызовом обратного вызова происходит что-либо вне его обратного вызова. –

ответ

2

Всегда promisify на самом низком уровне, в этом случае 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); 
       } 
      }); 
     }); 
    }; 
} 

Теперь выше код уровня становится очень простым:

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]); 
     }); 
    })); 
}; 

Чтобы предотвратить отказ одного scuppering все это, вы можете выбрать, чтобы поймать отдельные ошибки и придать какой-то по умолчанию;

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

Спасибо, я новичок в асинхронном вызове, я думал об этом по-другому! –

+0

Добавил некоторое исправление ошибок, которое может показаться вам полезным. –

-1

ли возвращение в вашей функции петли асинхронной когда все было сделано

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; 
      } 
     } 
    }) 
    }) 
}