Reputation: 2093
I'm using NodeJS and mysql2 to store data in my database. but their are times when I need to perform database saves synchronously, like this example:
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);
})
So how can I perform these two database saves synchronously. I don't think that doing it in the following manner is good code:
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);
})
})
So what kind of solutions do you propose?
Upvotes: 2
Views: 4440
Reputation: 1541
mysql2 has promise support built in (docs here).
Just import "mysql2/promise" in stead of "mysql2", and
all the relevant methods return promises:
import * as mysql from "mysql2/promise";
async function duStuff() {
const connection = await mysql.createConnection(...);
await connection.query(...);
}
Upvotes: 0
Reputation: 1073978
I don't think that doing it in the following manner is good code
It isn't, but only because of the
if (err) throw err;
part, which will not do anything useful. (It certainly won't make your function making these query
calls throw an exception; it can't, you function has already returned. All it does is throw an exception from the callback; query
probably ignores it.)
Other than that, it's the correct way to do this with NodeJS-style callbacks. More specifically:
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);
});
});
}
There are couple of things you can do to make that code easier to maintain:
One is to use promises, which you can use on any vaguely-recent version of Node (or via an npm
module). First we'd give ourselves a Promise-enabled version of query
. In Node v8 and above, you can do that like this:
const promisify = require("utils").promisify;
// ...
const queryPromise = promisify(connection.query.bind(connection));
Alternately there's the promisify
npm
module, or really this basic version is really trivial:
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);
});
};
}
Then:
function myFunctionToDoThisWork() {
return queryPromise(queryString1, [queryValues1])
.then(() => {
return queryPromise(queryString2, [queryValues2]);
})
.then(() => {
console.log('rent saved', results);
});
});
}
then consume it via:
myFunctionToDoThisWork().then(/*...*/).catch(/*...*/);
On Node v8 and higher, you can take that further with async
and await
:
async function myFunctionToDoThisWork() {
await queryPromise(queryString1, [queryValues1]);
await queryPromise(queryString2, [queryValues2]);
console.log('rent saved', results);
}
If you call it from an async
function, you'd consume it via await
. If calling it from a non-async
function, you consume it just like the promise version above (via then
).
Upvotes: 1