javascriptsqlnode.jsasynchronoussynchronous

Execute mysql query one after the other inside for loop in node js


I am trying to perform multiple SQL queries inside a for loop one after the other. What I am trying to achieve is that each iteration will use the output generated by the previous iteration query to generate a new query and execute it, but what happens is that due to the asynchronous nature of I/O in javascript, all the queries are getting executed all at once and throwing error as the result from the previous query is undefined as it's not yet executed.

My syntax is similar to this:-

var iterationCount = 10;
var query = "Initial SQL query";
for(i=0;i<iterationCount;i++) {
    result = executeSQLQuery(query);

    query = createQueryFromresult(result);
}

function executeSQLQuery(query) {
  // logic to execute the query
  return result;
}

function createQueryFromresult(result) {
  // logic to create a query by fetching some fields from the result 
  // depending upon some conditions
  return query;
}

Solution

  • The easiest way to handle this is with async / await. Notice that the await syntax lets you use asynchronous method codes in a sequence in an easy-to-read form. Also notice that you can await a function that returns a promise, or you can await an async function. They're actually the same thing with slightly different syntax.

    Something like this.

     /* promisified query method, suitable for await */
     function doQuery(conn,sql,args) {
         return new Promise (function( resolve, reject ) {
            conn.query(sql, args, function (error, results, fields) {
                if (error) return reject(error)
                resolve({results, fields})
            }) 
         })
     }
    
     /* your loop operation */
     async function whatever ( args ) {
          for (whatever conditions) {
             let queryOutput = await doQuery (conn, sql, [arg, arg])
             let firstColumn = queryOutput.results['first_column']
          }
          return resultValue
     }
    
     /* call your async function */
     whatever(args)
     .next (function (resultValue) {  whatever you need } )
     .catch (console.error)