Wait for an answer to continue a for Node.js

1

Good, I tell you my question: I have a function in node.js that what it does is to collect all the clients of a database SQL . I am using the mssql package for this but the issue is that for each client I must make another request to add more data to each of them. The problem is that the request is asynchronous and does not wait to receive the answer to continue with the next one, here the example:

exports.getClients = function(req, res) {

    var response = []

    new sql.Request()
        .execute('getClients')
        .then(function(clientes) {

            var clientesArray = clientes[0]

            for (var i = 0; i < clientesArray.length; i++) {

                new sql.Request()
                    .execute('getDireClients')
                    .then(function(dirents) {

                          //aquí es donde se añaden los datos a un cliente                                

                    }).catch(function(err) {
                        res.json({
                            "error": err.message
                        })
                    });
            }

        }).catch(function(err) {
            res.json({
                "error": err.message
            })
        });
};

How have I solved it? Well, doing a recursive function that would go through the array of clients by an index and once said index is equal to the size of the array that returns the response. (Share if it helps someone)

  exports.getClients = function(req, res) {

        var response = []
        var addedClientsCount = 0

        new sql.Request()
            .execute('getClients')
            .then(function(clientes) {

                var clientesArray = clientes[0]
                addDirentsToClient(clientesArray , addedClientsCount, res, response)

            }).catch(function(err) {
                res.json({
                    "error": err.message
                })
            });
    };

function addDirentsToClient (clients, addedClientsCount, res, response) {

      new sql.Request()
          .execute('getDireClients')
          .then(function(dirents) {

          if (addedClientsCount >= clients.length) {              
              res.json(response)
          }else{
            //aquí añado los datos al cliente, he suprimido 
            //  esta parte porque es larga
            response.push(clients[i])
            addedClientsCount = addedClientsCount + 1
            addDirentsToClient(clients, addedClientsCount, res, response)
          }

      }).catch(function(err) {
          res.json({
              "error": err.message
          })
      });
}

Then my question is:

Can this be done but with the first example, that is, with a for?

    
asked by Fabio Venturi Pastor 30.11.2016 в 19:18
source

2 answers

1

No, I do not think you can do that in a for , also, if your arrangement is moderately large, a recursive tour will eventually explode with a stackoverflow (without the .com).

It seems to me that what you are looking for is Promise.all , at Promise.all you can spend an arrangement of promises that you can fill in the for, and when you do Promise.all(miArregloDePromise).then( ... ) , in then you can assume that you receive an arrangement with the result of each promise you added.

Promise.all on MDN

    
answered by 30.11.2016 / 19:58
source
1

In the end I managed to do it with the Promise package as well comments @yms:

function addDirentsToClientes(clientes, res) {

  var count = 0
  var clientesDirents = []

    return clientes.reduce(function(promise) {

        return promise.then(function() {

        return new sql.Request()
              .input('codcli', sql.VarChar(8), clientes[count].CODCLI)
              .execute("getDirentsByCodCli")
              .then(function(dirents) {

                var cliente = JSON.parse(JSON.stringify(clientes[count]))
                count++

                cliente.dirents = dirents[0]
                clientesDirents.push(cliente)

                if (count >= clientes.length){
                  res.json(clientesDirents)
                }

              }).catch(function(err) {
                  res.json({
                      "error": err.message
                  })
              });
        });
    }, Promise.resolve());
}

If someone tells me a better way to do the above, I appreciate it. Very grateful @yms

    
answered by 01.12.2016 в 10:14