NodeJs:同步运行Mysql查询

时间:2018-03-04 19:21:00

标签: javascript node.js mysql2

我正在使用NodeJS和mysql2在我的数据库中存储数据。但是他们需要同步执行数据库保存时,例如:

if(rent.client.id === 0){
    //Save client
    connection.query('INSERT INTO clients (name, identity, licence, birthDate, address, phoneNumber, email) VALUES (?,?,?,?,?,?,?)', 
                     [/*Array of values*/],
                     function (err, results) {
        if (err) throw err;

        //Retrieve client id to use it in the next database save
        rent.client.id = results.insertId;
    })
}

//Save rent
connection.query('INSERT INTO rents (deliveryDate, returnDate, gasLevel, deliveryPoint, deliveryPrice, unitPrice, state, clientID, carID) VALUES (?,?,?,?,?,?,?,?,?)', 
                 [/*Array of values that contain the last inserted id clients*/],
                 function (err, results) {
    if (err) throw err;
    console.log('rent saved', results);
})

那么如何同步执行这两个数据库保存呢?我不认为以下面的方式做这件事是好的代码:

connection.query(queryString, 
                 [queryValues],
                 function (err, results) {
    if (err) throw err;
    connection.query(queryString, 
                     [queryValues],
                     function (err, results) {
        if (err) throw err;
        console.log('rent saved', results);
    })

})

那么你建议采用什么样的解决方案?

1 个答案:

答案 0 :(得分:1)

  

我不认为以下面的方式做这件事是好的代码

不是,但仅仅是因为

if (err) throw err;

部分,它不会做任何有用的事情。 (它肯定不会使你的函数使这些query调用抛出异常;它不能,你的函数已经已经返回。它只是从回调中抛出一个异常; query可能会忽略它。)

除此之外,这是使用NodeJS样式回调执行此操作的正确方法。更具体地说:

function myFunctionToDoThisWork(callback) {
    connection.query(queryString1, 
                     [queryValues1],
                     function (err, results) {
        if (err) {
            callback(err);
            return;
        }
        connection.query(queryString2, 
                         [queryValues2],
                         function (err, results) {
            if (err) {
                callback(err);
                return;
            }
            console.log('rent saved', results);
        });
    });
}

您可以采取以下措施使代码更易于维护:

一种是使用promises,您可以在任何模糊的Node版本(或通过npm模块)上使用。首先,我们给自己一个启用Promise的query版本。在Node v8及更高版本中,您可以这样做:

const promisify = require("utils").promisify;
// ...
const queryPromise = promisify(connection.query.bind(connection));

或者有promisify npm模块,或者这个基本版本真的很简单:

function promisify(f) {
    return function() {
        var t = this;
        return new Promise(function(resolve, reject) {
            var args = Array.prototype.slice.call(arguments);
            args.push(function(err, data) {
                if (err) {
                    reject(err);
                } else {
                    resolve(data);
                }
            });
            f.apply(t, args);
         });
    };
}

然后:

function myFunctionToDoThisWork() {
    return queryPromise(queryString1, [queryValues1])
        .then(() => {
            return queryPromise(queryString2, [queryValues2]);
        })
        .then(() => {
            console.log('rent saved', results);
        });
    });
}

然后通过:

消费它
myFunctionToDoThisWork().then(/*...*/).catch(/*...*/);

在节点v8及更高版本上,您可以使用asyncawait更进一步:

async function myFunctionToDoThisWork() {
    await queryPromise(queryString1, [queryValues1]);
    await queryPromise(queryString2, [queryValues2]);
    console.log('rent saved', results);
}

如果您从async功能调用它,则会通过await使用它。如果从非async函数调用它,则会像上面的promise版本一样使用它(通过then)。