ForEach wait for the select result to proceed

3

I have a forEach that goes through a list of codes and inside it I have a select that queries the records of the database. After forEach , the data is sent from my server to my client, but forEach does not wait for the result SELECT to reach to execute the next element.

How can I do to forEach expect the result

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

    
asked by anonymous 24.11.2017 / 11:53

3 answers

2

You can use Promise and Promise.all to do this. The async library is great 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);
    
24.11.2017 / 17:14
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: link

    
24.11.2017 / 12:43
2

I believe that db.query does not return a Promise , but you can create a promise so that it returns 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))
    
24.11.2017 / 13:10