Jump to content

Await / async functions


roboBen
 Share

Recommended Posts

Hey guys,

I need your help with a problem I’ve been able to walk around so far.
Namely, I want to make a mysql query in a node.js web socket:

 connection.query("SELECT * FROM DB WHERE id= ?;", [id], function(error, results, fields) {
            if (error) throw error;
         	// Code here...
        })

In the variable results I can now use the data in the form of a JSON object. That’s not a problem.
So far, I have done this so that when I wanted to make several queries, I have nested into each other. Like this:

 connection.query("SELECT * FROM DB WHERE id= ?;", [id], function(error, results, fields) {
            if (error) throw error;
         	 connection.query("SELECT * FROM DB WHERE id= ?;", [id], function(error, results, fields) {
            if (error) throw error;
         	// Code here...
        })
        })

But now I need that some queries are only carried out if certain conditions are met. As a result, the queries can no longer be logically nested.
That’s why I need something like this:

if(a == b) {
	 connection.query("SELECT * FROM DB WHERE id= ?;", [id], function(error, results1, fields) {
            if (error) throw error;
         	// Code here...
        })
}

if(c == b) {
	 connection.query("SELECT * FROM DB WHERE id= ?;", [id], function(error, results2, fields) {
            if (error) throw error;
         	// Code here...
        })
}

And after both if loops I can logically no longer access the values results1 and results2.
How can I do that? Do you need more information.

I hope for some answers.

 

Yours, Ben

Edited by roboBen
Link to comment
Share on other sites

You can always write the results to a global variable. You'll have to keep track of how many asynchronous operations are occurring so that you can know when to run a certain block of code.

Also, if you don't need to run different code for each query, I'd suggest making a named function and passing it as a callback to the queries.

/* Declare global variables */
var globalResults = [];
var numQueries = 0;

/* Run queries */
if(a == b) {
  numQueries++;
  connection.query("SELECT * FROM DB WHERE id= ?;", [id], queryCallback);
}

if(c == b) {
  numQueries++;
  connection.query("SELECT * FROM DB WHERE id= ?;", [id], queryCallback);
}

/* Function declarations */
function queryCallback(error, results, fields) {
  if (error) throw error;
  globalResults[globalResults.length] = results;
  handleResults();
}

function handleResults() {
  // Leave the function if there are queries that haven't been completed yet
  if(numQueries > 0) {
    numQueries--;
    return;
  }
  
  // Access query results
  for(var i = 0; i < globalResults.length; i++) {
    // Do something with globalResults[i]
  }
}

If you need to know which query each set of results came from, then you can store the query results in an object which identifies the results. This is less flexible but is necessary if each set of results has to be processed differently.

/* Declare global variables */
var globalResults = {
  resultsA : null,
  resultsB : null
};
var numQueries = 0;

/* Run queries */
if(a == b) {
  numQueries++;
  connection.query("SELECT * FROM DB WHERE id= ?;", [id], function(error, results, fields){
    if (error) throw error;
    globalResults.resultsA = results;
    handleResults();
  });
}

if(c == b) {
  numQueries++;
  connection.query("SELECT * FROM DB WHERE id= ?;", [id], function(error, results, fields){
    if (error) throw error;
    globalResults.resultsB = results;
    handleResults();
  });
}

/* Function declarations */
function handleResults() {
  // Leave the function if there are queries that haven't been completed yet
  if(numQueries > 0) {
    numQueries--;
    return;
  }
  
  // Access query results
  if(globalResults.resultsA) {
    // Do something with the results of the first query
  }
  
  if(globalResults.resultsB) {
    // Do something with the results of the second query
  }
}

 

Link to comment
Share on other sites

Thanks for responding!
Wouldn’t you have to create the function to stop the original function until it’s finished? Similar to for-loop or multiple functions of fs?

Could you explain to me again what these functions are for? If I go through this with sample numbers, it doesn’t make sense. But I’m the one who asks for help in the forum...

On 10/9/2021 at 8:39 PM, Ingolme said:
/* Function declarations */
function handleResults() {
  // Leave the function if there are queries that haven't been completed yet
  if(numQueries > 0) {
    numQueries--;
    return;
  }
  
  // Access query results
  if(globalResults.resultsA) {
    // Do something with the results of the first query
  }
  
  if(globalResults.resultsB) {
    // Do something with the results of the second query
  }
}

Thank you for your efforts and your time and I hope to get another answer from you.

Link to comment
Share on other sites

Javascript does not have any kind of command which stops the program until something has been completed. It is asychronous, the program continues running while callback functions are called when specific events occur. For this reason, anything you want to wait for has to be in a callback function.

When the program starts, it runs the queries. For each query it adds 1 to a counter (numQueries) to indicate that the query is now running.

Each query has a callback function that runs once the query has completed. This callback function stores the results of the query in a global variable for later use and then calls the handleResults() function.

The handleResults() function subtracts 1 from the counter I created earlier to indicate that this query has ended. I seem to have made a mistake though, it should look like this instead:

numQueries--;
if(numQueries > 0) {
  return;
}

If there are still unfinished queries, then the counter will be a value bigger than zero, so we will return from the function and do nothing. Once all the queries have ended, the counter numQueries should be zero, so we know that we can start processing the query results. The results will be stored in the global variable globalResults.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...