Does anyone know why the list remains empty even after await (Node.js)?

Asked

Viewed 46 times

0

static async readAll(){
    const data = []
    await mysql.query('SELECT * FROM registro', (err, result, fields) => {
        if (err) throw err;
        result.forEach((doc) => {
            const registro = new Registro(doc);
            data.push(registro);
        });
    });
    console.log(data);
}

Even after I say "wait" for the execution of the code it does not add my object to my "date" array, someone knows how to solve?

1 answer

2

The method mysql.query probably not a Promise, then use the await it won’t do any good.

You must deal with the value data within the callback, given the asynchronous nature of Javascript. When you give the console.log(data) outside the callback, to query probably still being loaded.

See a demonstration of this asynchronous flow:

console.log(1);

// Imagine o método `fetch` como algo que faz uma consulta ao banco de dados:
fetch('https://api.github.com/users/lffg')
  .then(() => console.log(2));
  
console.log(3);

As you can see above, the console.log(3) is displayed before the 2, since the latter is still being "loaded", since it is within a then.

So, if you want to work with the data in your function readAll, will have to do it inside the callback:

static readAll() {
  mysql.query('SELECT * FROM registro', (err, result, fields) => {
    if (err) throw err;

    const data = [];
    result.forEach((doc) => {
      const registro = new Registro(doc);
      data.push(registro);
    });

    // Aqui você terá acesso ao `data`. Sem problemas. :)
    console.log(data);
  });
}

Already if you want to use the value as return of the method, it is worth using a Promise, so you can use await in another part of your code:

class MyService {
  static readAll() {
    // Note que o método `readAll` retorna uma nova promessa:
    return new Promise((resolve, reject) => {
      mysql.query('SELECT * FROM registro', (err, result, fields) => {
        if (err) reject(err);

        // Usei o `Array.prototype.map` para eliminar a necessidade do `forEach`.
        const data = result.map((doc) => new Registro(doc));

        // A promessa eventualmente irá se resolver com o valor `data`:
        resolve(data);
      });
    });
  }
}

// E em outra parte do código:
async function main() {
  const data = await MyService.readAll();
  console.log(data);
}

For further insight, I think it’s important to read other resources on promises, such as:

And also worth reading about the Array.prototype.map.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.