Nodejs使用瀑布异步eachSeries

时间:2015-07-24 19:32:47

标签: node.js asynchronous

下午好,我正在开发一个后端应用程序,我需要在每个系列中使用async,但是,我的当前函数在结束asyc.waterfall([])之前返回到eachSeries,有时候对于每个系列在完成阵列之前。我已经完成了各种调试,但还是找不到我的错误。如果有人可以帮助我。

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();
    }); 
}

1 个答案:

答案 0 :(得分:1)

首先,使用瀑布对于你想要做的事情来说有点过分。瀑布旨在处理从一次迭代传递到下一次迭代的值。来自异步文档:

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'
});

你没有这样做。相反,只需使用Series即可。这是我认为你想要完成的工作(简化)示例。 (请注意,我在我的示例中取出了setImmediate,但它也适用于它:)

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
/*

此外,在您的代码中,您正在调用acabou()

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

这定义在哪里?如果reposta永远== false,您的回调将从不开火,您的循环将永远不会完成。

最后一点:Node本质上是异步的。通过在阻塞代码循环中运行循环,此活动变得异常同步。如果你能以一种并行工作的方式重写它,你会发现它更有效。