lecarpetron dookmarion
lecarpetron dookmarion

Reputation: 721

New to NodeJS - is it possible to await a callback function?

What if I have a code like this:

var mysql = require('mysql');
var pool  = mysql.createPool(...);

pool.getConnection(function(err, connection) {
  if (err) throw err; // not connected!

  // Use the connection
  connection.query('SELECT something FROM sometable', function (error, results, fields) {
    // When done with the connection, release it.
    connection.release();

    // Handle error after the release.
    if (error) throw error;

    // Don't use the connection here, it has been returned to the pool.
  });
});

The logic from initializing the pool until the entire getConnection process is located in an async function. So what happens is, when deployed in AWS, logs in getConnection are not logged because the handler finishes execution before the callback is processed. Due to this, the logs from line "if (err) throw err" is not seen in AWS cloudwatch logs.

Is there a workaround for this? I simply want to await the callback function in pool.getConnection

I did my research but all I found were specific implementations for specific scenarios, none quite similar to my scenario.

Upvotes: 0

Views: 59

Answers (1)

jfriend00
jfriend00

Reputation: 708036

is it possible to await a callback function?

No, not with a plain callback that does not use promises.

await only does something useful when you're awaiting a promises. The connection.query() function call you show in your question does NOT use promises so there is no place for await with that function call as it is.

But, you can either wrap the connection.query() in a function that returns a promise (referred to as promisifying it) and create a new function that is promise-based.

Here's a look at how promisifying works. You don't show the overall context of your code. The promisifying would more typically be done at a more centralized location, but I've shown it here in the only context that you've shown:

const { promisify } = require('util');

async function someFunc() {
    const pool = mysql.createPool(...);
    pool.getConnectionP = promisify(pool.getConnection);
    let connection;
    try {
         connection = await pool.getConnectionP();
         connection.queryP = promisify(connection.query);
         const results = await connection.queryP('SELECT something FROM sometable');
         return results;
    } catch(e) {
         console.log(e);
         // handle errors here
    } finally {
         if (connection) {
               connection.release();
         }
    }
}

Or, your database already has a promise-interface and you can just use that (which would be my recommendation). See the mysql2/promise interface here where these functions are already converted to use promises and you can then use await with them.

Upvotes: 1

Related Questions