NodeJs: 运行 Mysql 同步查询
NodeJs: Run Mysql queries synchronously
我正在使用 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);
})
})
那么您提出了什么样的解决方案呢?
I don't think that doing it in the following manner is good code
不是,只是因为
if (err) throw err;
部分,不会做任何有用的事情。 (它肯定不会让你的函数使这些 query
调用抛出异常;它不能,你的函数已经 已经返回 。它所做的只是从回调;query
可能会忽略它。)
除此之外,这是使用 NodeJS-style 回调执行此操作的正确方法。更具体地说:
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,您可以在任何 vaguely-recent 版本的 Node 上使用它(或通过 npm
模块)。首先我们给自己一个 query
的 Promise-enabled 版本。在 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(/*...*/);
在 Node v8 及更高版本上,您可以使用 async
和 await
更进一步:
async function myFunctionToDoThisWork() {
await queryPromise(queryString1, [queryValues1]);
await queryPromise(queryString2, [queryValues2]);
console.log('rent saved', results);
}
如果您从 async
函数调用它,您将通过 await
使用它。如果从非 async
函数调用它,您将像上面的 promise 版本一样使用它(通过 then
)。
我正在使用 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);
})
})
那么您提出了什么样的解决方案呢?
I don't think that doing it in the following manner is good code
不是,只是因为
if (err) throw err;
部分,不会做任何有用的事情。 (它肯定不会让你的函数使这些 query
调用抛出异常;它不能,你的函数已经 已经返回 。它所做的只是从回调;query
可能会忽略它。)
除此之外,这是使用 NodeJS-style 回调执行此操作的正确方法。更具体地说:
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,您可以在任何 vaguely-recent 版本的 Node 上使用它(或通过 npm
模块)。首先我们给自己一个 query
的 Promise-enabled 版本。在 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(/*...*/);
在 Node v8 及更高版本上,您可以使用 async
和 await
更进一步:
async function myFunctionToDoThisWork() {
await queryPromise(queryString1, [queryValues1]);
await queryPromise(queryString2, [queryValues2]);
console.log('rent saved', results);
}
如果您从 async
函数调用它,您将通过 await
使用它。如果从非 async
函数调用它,您将像上面的 promise 版本一样使用它(通过 then
)。