Make one asynchronous function wait for another

Asked

Viewed 816 times

2

I am developing a Javascript system with Node.JS and Redis, however, due to the asynchronous functions the loop ends before the functions, which causes the response array to be misordered or the time out on the server.
Faced with my problem, it is possible to make the functions wait for each other?
What would be a possible solution to my problem?

Code of what I’ve done so far:

var express = require('express');
var router = express.Router();
var redis = require('redis'),
    client = redis.createClient(32769, '192.168.99.100');

client.on("error", function (err) {
    console.log("Error " + err);
});

router.post('/UsuarioLogadoPossuiAcoes', function (req, res) {

    var templateKey = 'Usuario:' + req.body.token;

    var resposta = [];

    for (var i = 0; i < req.body.Acoes.length ; i++) {

        var Namespace = req.body.Acoes[i].split('.');
        var Verbo = Namespace.pop();
        Namespace = Namespace.join('.');
        var chave = templateKey + ':' + Namespace;

        client.exists(chave, function (err, existe) {

            if (existe == 1) {

                client.sscan(chave, 0, 'MATCH', Verbo, function (err, resultado) {

                    resposta[i] = (resultado[1].length > 0);
                    console.log(i + ' - ' + resposta[i]);
                    console.log(chave + '.' + Verbo);

                    //Verifica se as validações terminaram, encerra a conexão com o redis e responde a conexão
                    if (req.body.Acoes.length == resposta.length) {

                        client.end();
                        res.json(resposta);

                    }

                });

            } else {

                // Procura no banco relacional e faz o cache no redis

                resposta[i] = false;
                console.log(i + ' - ' + resposta[i]);

                //Verifica se as validações terminaram, encerra a conexão com o redis e responde a conexão
                if (req.body.Acoes.length == resposta.length) {

                    client.end();
                    res.json(resposta);

                }
            }
        });
    }    
});

module.exports = router;
  • Hello, Matthew. Can you explain better what you are doing and what lines do you believe are the cause of the problem? There may be a better solution than stopping the entire execution, as you lose most of the advantages of using Nodejs.

2 answers

3

The ideal would be that everything inside the for occur within a separate function, but I believe only change this:

for (var i = 0; i < req.body.Acoes.length ; i++) {
   //...
}

for:

req.body.Acoes.forEach(function(acao, i, Acoes) {
  //...
});

It would solve your problem. The loop ends before the asynchronous functions end, but in the second case the index variable is contextualized within the body of the function, so even after the asynchronous function ends, the value of i will remain the same.

Remembering that within the function of the forEach you would stop using req.body.Acoes[i] to reference each item and use the parameter acao (or the name you prefer).

Reference for documentation of forEach in the MDN.

1


Well, what I did to solve my problem was a recursive function with a callback and in the callback I give the answer. Currently this is solving my problem

Browser other questions tagged

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