Reputation: 25
It's my code:
const mariadb = require('mariadb');
var test = async function(){
var ret = "";
await mariadb.createConnection({
host: "localhost",
user: "dave",
connectionLimit: 5,
password: "!@#",
database: "db",
rowsAsArray: false
}).then((data)=>{
ret = "test";
});
return ret;
}
console.log(test());
How can I get a return from then using await?
I know that similar questions have been raised in many cases, but I could not find any using mariadb.
Upvotes: 1
Views: 1686
Reputation: 2815
Already I can see a few pitfalls, which as beginners you will come across in this code:
avait
is waiting for results to be returned, as he will get Promisses
to solve itthen
solves promises asynchronouslyasync
always returns promisesAfter a moment of delight, 'async / await' now I try to avoid him. Mainly because every function in which I use the asynchronous function must also be asynchronous until you use then
, eg make small test:
let test = async function() {
let x = await 11
return 1;
}
console.log(test()) //returns: Promise { <pending> }
There is nothing asynchronous there, but adding async / await
has caused a mess.
Now fixes for your code
const mariadb = require('mariadb');
// use local scope `let` instead global `var`
let test = async function(){
let conn = await mariadb.createConnection({
host: "localhost",
user: "dave",
connectionLimit: 5,
password: "!@#",
database: "db",
rowsAsArray: false
});
return conn.query("SELECT 1 as val") // no sense using `avait` because `test()` returns `promise`
}
test().then(function(rows) { console.log(rows)});
and without asnc. then
can return promise and this can be resolbed by next then
mariadb.createConnection(...).then(conn => { // create connection
return conn.query("SELECT 1 as val") // make query
}).then(rows => { //get result
console.log(rows)
}).catch(err => console.error(err)) // get errors
By the way: get interested in query builder, for example knex.js. It allow write code independent from database engine.
Let's start with the fact that Node is based on events.
Let's take an example of receiving data from the database. In PHP / C ++, you make an query, wait, receive a result. And this behavior simulates by the await
. (Await appeared somewhere near version 8)
Normally, the code in the Node works so that you execute the query, and Node creates a new thread. Old run next instruction, in new you will get the results. (OK, I'm lying, but it's easier to explain).
So, you have to handle the event of receiving the data. And more specifically the promise
of providing data. By await
,.then ()
, orcallback (hell)
You try return ret
, but this code first make return ret
and after make assigment.
await
"returns" data, so you should use let var_name = await asyncFunction()
I'm guess, that you want this:
let getSomeDataFromDB = function(){
return mariadb.createConnection([skip]).then(conn => {
return conn.query("SELECT 1 as val")
})
}
let rows = await getSomeDataFromDB()
In this function you return promise, who return promise. And by await
this promise chain is resolved.
But here is a "small" error in the code. Because you are connecting and you are not ending your connection anywhere. Therefore, it is better to have a global connection object, or use something like this:
let getSomeDataFromDB = function(){
return new Promise(function(resolve, reject){
mariadb.createConnection([skip]).then(conn => {
conn.query("SELECT 1 as val")
.then(rows=>resolve(rows))
.catch(e=>reject(e))
.then(()=>conn.close())
}).catch(e => reject(e))
})
}
let rows = await getSomeDataFromDB()
And here you discover another important thing: resolve
does not interrupt the execution of the code. Despite the data being returned to the user, you can still do something.
Or the same with await
let getSomeDataFromDB = async function(){
let conn = await reateConnection([skip])
let rows = await conn.query("SELECT 1 as val")
await conn.close();
return rows;
}
let rows = await getSomeDataFromDB()
Upvotes: 1