Fortunato
Fortunato

Reputation: 109

Nodejs Async eachSeries with waterfall

Good afternoon I'm developing a backend application where I need to use the async with a eachSeries , however, my current function is returning to the eachSeries start before the end asyc.waterfall ([] ), sometimes for eachSeries before finishing the array . I've done all sorts of debug and could not yet find my mistake. If someone can help me.

var filaPosicoes = function filaPosicoes(posicoes) {
    var n = 0;
    async.eachSeries(posicoes, function(posicao, eachCallback) {
        global.posicao = posicao;
        n++;
        async.series([
            //tratar os campos das posições
            function(callback) {
                console.log("1");
                //global.posAnterior = null;            
                tratarCampos(function(resposta){
                    callback();
                });
            },
            //Atualizar dados do motorista na posição
            function(callback) {
                console.log("2");
                atualizarDadosPosicao(function(resposta){
                    callback();
                });
            },
            //buscar a posição anterior 
            function(callback) {
                console.log("3");
                buscarAnterior(function(resposta) {
                    callback();
                });
            },
            //verificar se é a primeira posição do rastreador
            function(callback) {
                console.log("4");
                primeiraPosicao(function(resposta) {
                    //se retornar false já fez o que era necessário para a posição, vai para a próxima
                    if (resposta == false) {
                        eachCallback();
                    }
                    else {                  
                        callback();
                    }
                });
            },
            //Toda posição parada com ponto ou endereço
            function(callback) {
                console.log("5");
                verificarDestinos(function(resposta) {
                    //somente posições desligadas tem endereço
                    if (resposta == false && global.posicao.ignicao == 0) {
                        buscarEndereco(function(resposta){
                            callback();
                        });
                    }
                    else {
                        callback();
                    }
                });
            },
            //verificar se a posição não esta no futuro
            function(callback) {
                console.log("6");
                posicaoFuturo(function(resposta) {
                    //se retornar false já fez o que era necessário para a posição, vai para a próxima
                    if (resposta == false) {
                        eachCallback();
                    }
                    else {                  
                        callback();
                    }
                });
            }, 
            //chama a função do calculo de odometro
            function(callback) {
                console.log("7");
                calcOdometro(function(resposta){
                    callback();
                });
            },
            //verifica a bateria
            function(callback) {
                console.log("8");
                bateriaConectada(function(resposta){
                    callback();
                });
            },
            //verifica a distância entre as posições
            function(callback) {
                console.log("9");
                ignorarDistancia(function(resposta) {
                    //se retornar false já fez o que era necessário para a posição, vai para a próxima
                    if (resposta == false) {
                        eachCallback();
                    }
                    else {                  
                        callback();
                    }
                });
            },
            //verifica a ignição
            function(callback) {
                console.log("10");
                verificarIgnicao(function(resposta) {
                    if (resposta == false) {
                        eachCallback();
                    }
                    else {                  
                        callback();
                    }
                });
            },
            //Verificação de rastreador portatil
            function(callback) {
                console.log("11");
                rastreadorPortatil(function(resposta) {
                    //se a variação de tempo for maior que 0 faz a verificação da aceleração
                    if (resposta == 'aceleracao') {
                        verificarAceleracao(function(response) {
                            if (response == false) {
                                eachCallback();
                            }
                            else {
                                callback();
                            }
                        });
                    }
                    else {
                        callback();
                    }
                });
            },
            //verifica se é uma posição desligada e faz os devidos tratamentos
            function(callback) {
                console.log("12");
                if(global.posicao.ignicao == 0) {
                    posicaoDesligada(function(resposta) {
                        if (resposta == false) {
                            eachCallback();
                        }
                        else {
                            callback();
                        }
                    });
                }else{
                    callback();
                }
            },
            function(callback) {
                console.log("13");
                finalizarAtivacao(function(resposta){
                    callback();
                });
            },
        ], 
        function(err, result) {
            setImmediate(function() {
             eachCallback(); 
            });  
        });
    },
    //quando acabar o loop de posições busca no posicoes_entrada novamente
    function(err) {
        buscarPosicoes();
    }); 
}

Upvotes: 0

Views: 1121

Answers (1)

brandonscript
brandonscript

Reputation: 72855

First, using Waterfall is a bit overkill for what you’re trying to do. Waterfall is designed to handle values passed from one iteration to the next. From the async docs:

async.waterfall([
    function(callback) {
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback) {
      // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback) {
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    // result now equals 'done'
});

You're not doing any of this. Instead, just use Series. Here's a working (simplified) example of what I think you're trying to accomplish. (Note that I took out setImmediate in my example, but it does work with it as well):

var async = require('async');

(function doThis() {
    var n = 0;
    async.eachSeries([1, 2, 3, 4], function(x, eachCallback) {
        n++;
        async.series([
            function(callback) {
                console.log(x + " 1");
                setTimeout(function(){
                    callback();
                }, 200);
            },
            function(callback) {
                console.log(x + " 2");
                setTimeout(function(){
                    callback();
                }, 200);
            },
            function(callback) {
                console.log(x + " 3");
                setTimeout(function(){
                    callback();
                }, 200);
            }
        ], 
        function(err, result) {
            eachCallback(); 
        });
    },
    function(err) {
        console.log('done');
    }); 
})();

/* Output:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1
4 2
4 3
done
/*

Also, in your code, you're calling acabou():

if (resposta == false) {
    acabou();
} else {
    callback();
}

Where is this defined? If reposta ever == false, your callback will never fire and your loop will never finish.

One final note: Node is intended to be asynchronous by nature. By running a loop within a loop of blocking code, this activity becomes exceptionally synchronous. If you can rewrite it in a way that works in parallel, you'll find it way more performant.

Upvotes: 1

Related Questions