NodeJS executing multiple database queries using async library I have a use case where I need to run multiple tasks in series. Each task is required to perform some database operations. In my code step_1, step_2 and step_3 are these task which get executed in series (Async Waterfall)
Following is my code
const config = require('config.json');
var mysql = require('mysql');
var async = require(&quot;async&quot;);

const pool = mysql.createPool({
  host: config.database.dbhost,
  user: config.database.dbuser,
  password: config.database.dbpassword,
  database: config.database.dbname
});

exports.handler = (event, context, callback) =&gt; {
    
    pool.getConnection((err, connection) =&gt; {
    if (err) throw new Error(&quot;Unable to get connection &quot; + JSON.stringify(err));
    
      async.waterfall([
            step_1,
            step_2,
            step_3
        ], function (err, result) {
            if(err){                
                throw new Error(&quot;something went south : &quot;+ JSON.stringify(err));
            }else{
                connection.release();
                callback(null, &quot;SUCCESS: &quot; + JSON.stringify(result));
            }           
        });

        function step_1(cb){
            connection.query(&quot;step 1 query&quot;, function (error, response) {
                      if (error){
                        cb(null,error,null);
                      }
                      let id=result.insertId;
                      cb(null,null,id);
            });
        }

        function step_2(error,id,cb){
            if(error){
                cb(null,error);
            }else{
                connection.query(&quot;step 2 query&quot;,,function (err,result){
                        if (err){
                          connection.query(&quot;error logging query&quot;,
                          function(er,result){
                            if (er) cb(null,er,null);                    
                          });
                          cb(null,err,null);
                        }
                    cb(null,null, id, result);
                });
            }
        }

        function step_3(error, id,result,cb){
            if(error){
                cb(error,null);
            }else{
                connection.query(&quot;step 3 query&quot;,function(err,result){
                    if (err) cb(err,null);                  
                    cb(null,result);
                });
            }
        }

    });
};

Although I have used a library to avoid nesting callbacks within callbacks, it still feels like bit callback-ish. Is there a better way to achieve my use case? Anything I can improve in my code, any suggestions please.
I have only included relevant parts of code, kindly let me know if any additional information is required.
A couple of helper functions will aid in flattening your callback chain:
function getConnection() {
  return new Promise((res, rej) =&gt; {
    pool.getConnection(function (err, connection) {
      if (err) {
        rej(err);
      } else {
        res(connection);
      }
    });
  });
}

function query(connection, sql, params) {
  return new Promise((res, rej) =&gt; {
    connection.query(sql, params, function (err, rows) {
      if (err) {
        rej(err);
      } else {
        res(rows);
      }
    });
  });
}

Then you can do something like:
async function step_1(connection) {
  const rows = await query(connection, 'step 1 query');
  return rows.insertId;
}

function step_2(connection, id) {
  return query(connection, 'step 2 query', id);
}

function step_3(connection, id, result) {
  return query(connection, 'step 3 query', id, result);
}

exports.handler = async (event) =&gt; {
  const connection = await getConnection();
  try {
    const id = await step_1(connection);
    const rows = await step_2(connection, id);
    const result = await step_3(connection, id, rows);
    return JSON.stringify(result);
  } finally {
    connection.release();
  }
};