简体   繁体   中英

Making a synchronous Node.JS for loop

I've got the following for loop. It works fine, besides the fact that it doesn't wait for the database query to finish before moving on. I understand that node is asynchronous. That's the issue. I need the easiest method to make the for loop run synchronously all the way through before looping.

var users = guild.members.map(member => member.id)
  console.log(users.length)
  for (var i = 0; i < users.length; i++) {
    console.log(i)
    connection.query("SELECT serverID, userID FROM serverusers WHERE serverID = ? && userID = ?", [guild.id, users[i]], function (err, result) {
      console.log(i + ":" + result)
      if (err) {
        console.log(colors.red(err.stack))
      }
      if (!result) {
        connection.query("INSERT INTO serverusers (serverID, userID) VALUES (?, ?)", [guild.id, users[i]])
      }
    })
  }

My end goal is to go through that map of users and check if each user is already in the database. If the user isn't, then add the user

Note: I'm using a MySQL database.

Note 2: The main solution I'm finding online is using the async library. I looked through its documentation and I couldn't find out which part of the library is used with for loops. Maybe an answer to this might help fix my issue.

Thanks!

Fixed it! It's not a proper solution but it solves my problem nonetheless. I simply condensed my for loop into one line. Here's my new code:

var users = guild.members.map(member => member.id)
  console.log(users.length)
  for (var i = 0; i < users.length; i++) {
    connection.query("INSERT IGNORE serverusers (serverID, userID) VALUES (?, ?)", [guild.id, users[i]])
  }

Thanks to anyone to contributed to this post :)

I see your answer but i thought I would provide an alternative because I don't think your answer does what you expect.

  1. If your async functions fail ( connection.query ) then you will never know.

  2. Anything after the for loop will likely run before those users are inserted.

Anyways, here's my answer using promises.

 function query (statement, params) { return new Promise(function (resolve, reject) { connection.query(statement, params, function (err, result) { if (err) reject(err); resolve(result); }) }) } var users = guild.members.map(member => member.id); var queries = users .map(u => query("INSERT IGNORE serverusers (serverID, userID) VALUES (?, ?)", [guild.id, u]); Promise.all(queries) .then(results => console.log('now it\\'s done', result)); .catch(err => console.log('whoopsies', err)); 

With the async library you can use the following methods:

async.each :

async.each(users, asyncFunctionToDealWithEachUser, callbackForWhenAllUsersHaveBeenProcesssed)

or

async.times

async.times(users.length, functionToRunForEachUser, callbackForWhenAllUsersHaveBeenProcessed);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM