Reputation: 25
I am making a request to a mySQL Database and want to work with the returned results. I have the async function
async function doQuery(query) {
try {
console.log('0. connection start');
var connection = MySQL.createConnection({
host: "xxxxxxxx",
user: "yyyyyyyy",
password: "zzzzzzzz"
});
console.log('1. Connection set up. Connecting...');
var queryResults;
await connection.connect(function(err) {
if (err) console.log(err);
console.log("2. Connected!");
connection.query(query, function(err, result) {
if (err) console.log(err);
queryResults = JSON.parse(JSON.stringify(result));
console.log("3. " + util.inspect(result, {depth: 4}));
console.log("3.5 " + util.inspect(queryResults, {depth: 4}));
connection.end();
});
})
console.log ("results before return:" + JSON.stringify(queryResults));
return queryResults;
}
catch (err){
console.log("async err: " + err);
}
}
The function is then called from another function:
function handle async(handlerInput) {
console.log("ExecuteDBSearchHandler");
var query = buildQuery(handlerInput);
try{
var resultsPromise = doQuery(query)
.then(results => {
console.log("4. final results: " + results);
const count = results.length;
var speechText = 'Abfrage Erfolgreich, es gab ' + count + " Ergebnisse.";
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Abfrage Erfolgreich', speechText)
.withShouldEndSession(false)
.getResponse();
})
}
catch (err){
console.log("error:" + err);
}
}
This code is to be used in a nodejs Alexa skill. When the function runs, I would expect the outputs in the log to be ordered ascending. The output I consistently get is 0, 1, 4, 2, 3, 3.5. The .then part is executed before the actual connection is established and the database queried.
Instead of the .then, I tried a simple await before, making the line
var results = await doQuery(query);
This lead to the exact same result. I am at a loss as to why await is infact not waiting. As a sidenote: While inside the block
connection.query(query, function (err, result) {
if (err) console.log(err);
queryResults = JSON.parse(JSON.stringify(result));
console.log("3. " + util.inspect(result, {depth: 4}));
console.log("3.5 " + util.inspect(queryResults, {depth: 4}));
connection.end();
});
queryResults shows results (in the debug log step 3.5). In the line
console.log ("results before return:" + JSON.stringify(queryResults));
it returns undefined. I tried so many things to get the results to the function scope of doQuery, but I can't seem to achieve that. Does the await fail due to this? And how can I fix it? I have read upwards of a dozen articles and docs about async/await and promises, yet I can't figure this out.
Upvotes: 1
Views: 1376
Reputation: 6058
You need to wrap your callback function in Promise to make use of await
keyword
For example:
async function dbQuery(query) {
try {
const connection = MySQL.createConnection({
host: "xxxxxxxx",
user: "yyyyyyyy",
password: "zzzzzzzz"
});
return new Promise(function(resolve, reject) {
connection.connect(function(err) {
if (err) reject(err);
connection.query(query, function (err, result) {
if (err) reject(err);
connection.end();
resolve(JSON.parse(JSON.stringify(result)));
});
});
});
} catch {
console.error("async err: " + err);
}
}
The one can also use util.promisify to wrap callback
in promise
Upvotes: 2