Foreach wait for the select result to proceed

Asked

Viewed 707 times

3

I have a forEach which traverses a code list and within it I have a select that queries the database records. After the forEach, data is sent from my server to my client, but forEach does not expect the result of SELECT arrive to execute the next element.

How can I make for the forEach await the outcome

lista.forEach(function (row) {
   db.query("select * from cad_prospectos where = ?", [row.codigo], function(err, pesquisa){
     result.push(pesquisa)
   })
})
cb(result)   

my return function cb returns empty

  • Putting the code you currently have will help answer the question...

  • I put the code I hope you can understand.

  • I could tell if db.query returns a Promise? By the way, is he native to Nodejs or is he from some package?

  • He’s from the Firebird package Firebird.attach(firebirdConfig, function (err, db)

  • If query returns a Promisse can store all in an array and use Promisse.all

  • [https://stackoverflow.com/questions/36547292/use-promise-to-process-mysql-return-value-in-node-js] I was able to find a good way to do it here, my query does not return a Promisse, so I made some modifications following the example of this link.

Show 1 more comment

3 answers

2

Work with Promises:

function consulta(lista) {
    var defer = $q.defer();
    var pesquisas = [];
    var queue = 0; // tamanho da fila a processar
    lista.forEach(function (row) {
       queue++; // adiciona uma pesquisa na fila
       db.query("select * from cad_prospectos where = ?", [row.codigo], function(err, pesquisa){
         pesquisas.push(pesquisa);
         queue--; // pesquisa terminada, sai da fila
         if(queue === 0) { 
            // quando a fila zerar, retorna todas as pesquisas
            defer.resolve(pesquisas); 
         }
       });
    });
    // retorna uma promessa de pesquisas;
    return defer.promise;
}

To consume this:

consulta()
  .then(function (pesquisas) { 
    console.log('pesquisas', pesquisas); 
   });

To learn more: https://www.promisejs.org/

2

I believe that the db.query does not return a Promise, but you can create a precedent for it to return when there is a result for your query, something like the code below;

// Função a ser executada para cada elemento da lista
var fn = function asyncQuery(row) {
  // Retorna uma promise que será finalizada quando o db.query for executado
  return new Promise(resolve => {
    db.query("select * from cad_prospectos where = ?", [row.codigo], function(err, pesquisa) {
      resolve(pesquisa)
    })
  });
};

// Executa a função fn para cada elemento da lista
var promises = lista.map(fn)

// Aguarda a finalização de todas as promises e obtem seu resultado
Promise.all(promises).then(result => cb(result))

  • 1

    Yes it helped me enough I’m almost getting, I’m searching in the library of "async" if there is any function that can help me too.

2


You can use Promise and Promise.all to do that. The async library is excellent but it made more sense before the Promises were integrated into the language.

So your code could be:

function selectAsync(cod) {
  return new Promise((res, rej) => {
    db.query("select * from cad_prospectos where = ?", [cod], (err, data) => {
      if (err) rej(err);
      else res(data);
    });
  });
}

const selects = lista.map(row => selectAsync(row.codigo));
Promise.all(selects).then(cb).catch(console.log);
  • 1

    Yes, that worked well I only made some changes to return to my client, it did not stay as I thought it would be but this working perfectly and this is what matters, thank you very much.

Browser other questions tagged

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