1

I wrote the following code, where I have a post request that executes 2 queries and some other operations:

router.post('/', (req, res) => {
    dbController.query(
        "SELECT * FROM users WHERE username = 'myUserName'",
        (err, result) => {
            console.log('<---- 1 ---->')
        }
    )
    // do something
    console.log('<---- 2 ---->')
    // do something
    dbController.query(
        "SELECT * FROM users WHERE username = 'myUserName'",
        (err, result) => {
            console.log('<---- 3 ---->')
    })
    res.send('ok')
})

I want to execute all instructions inside the function sequentially, so instead of getting this output (which is the one I get after executing the code):

<---- 2 ---->
<---- 1 ---->
<---- 3 ---->

I wanna get this one:

<---- 1 ---->
<---- 2 ---->
<---- 3 ---->

Note that after adding the keyword async to the function and await to the queries, nothing changes

arrmani88
  • 756
  • 8
  • 25

2 Answers2

1

Since you give dbController.query a callback function (err, result) => {...} as third parameter, it does not return a promise, but instead invokes the callback asynchronously. If you wrap dbController.query in util.promisify, you get a function that returns a promise which

  • either resolves to result, which you can await,
  • or rejects as err, which you can catch.

The two flavors are functionally equivalent, but with util.promisify, you can use async and await:

router.post('/', async (req, res) => {
  var queryPromise = util.promisify(dbController.query.bind(dbController));
  try {
    var result = await queryPromise("SELECT * FROM users WHERE username = 'myUserName'")
    console.log('<---- 1 ---->')
    console.log('<---- 2 ---->')
    result = await queryPromise("SELECT * FROM users WHERE username = 'myUserName'")
    console.log('<---- 3 ---->')
    res.send('ok')
  } catch(err) {
    res.status(400).send(err);
  }
})

(Many other database client libraries offer the promise flavor out of the box.)

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • Sorry, [`mysql`](https://www.npmjs.com/package/mysql) does _not_ offer the promise flavor directly, but you can achieve it with `util.promisify`. – Heiko Theißen Jun 15 '22 at 16:01
0

You need to wrap your logic in a .then() Your code should look something like this:

router.post('/', (req, res) => {
    dbController.query(
        "SELECT * FROM users WHERE username = myUserName",
        (err, result) => {
            console.log('<---- 1 ---->')
        }
    ). then(async function(rows){
// do something
    console.log('<---- 2 ---->')
    // do something
})
dbController.query(
        "SELECT * FROM users WHERE username = myUserName",
        (err, result) => {
            console.log('<---- 3 ---->')
    })
    res.send('ok')
})

You might also need to wrap the second query in a .then()

Mohammed Saber
  • 141
  • 2
  • 12
  • Hello, thanks for your answer, but this will not work because: `TypeError: dbController.query(...).then is not a function` – arrmani88 Jun 15 '22 at 15:12