在节点上执行异步多个 Mysql 查询

perform async multiple Mysql queries on Node

我在 Mysql 中使用节点,这是我的问题。

我正在尝试将新照片添加到我的数据库中并return它作为一个数组

这是我的功能:

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}

插入效果很好,但我无法检索结果以将它们发送回客户端。 (我的数组是空的)

谢谢。

完成所有操作后,在您的异步循环函数中执行 return

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

始终在最低级别进行承诺,在本例中为 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]);
        });
    }));
};

为防止单一故障破坏整个过程,您可以选择捕获个别错误并注入某种默认值;

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