Dave
Dave

Reputation: 25

return value from mariadb in function nodejs

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

Answers (1)

bato3
bato3

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 it
  • then solves promises asynchronously
  • function defined as async always returns promises

After 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.

Update

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)

first code explanation:

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

Related Questions