Para loop com os métodos GET e o CouchDB operações dentro async.js a série não executar mais de uma vez

StackOverflow https://stackoverflow.com//questions/22073762

Pergunta

Eu estou fazendo consecutivos http get chamadas usando async.js a série, que é dentro de um loop for.Primeiro eu obter um número de resultados de uma consulta da API, então eu executar outra consulta em cada um dos resultados.Os resultados são armazenados em uma matriz e, em seguida, salva um banco de dados CouchDB.Porque o número de resultados é limitado a 200, eu tenho que fazer isso várias vezes (daí o loop for).A estrutura básica do código é o seguinte (código completo abaixo)

for (...) {
  async.series(
     [
       function(){ http get method }, 
       function (){ async.eachSeries(){ http get method }, callback function }
     ],
     function(){ database operations }
  );//end series
}//end for loop

O meu problema é que o loop é executado apenas uma vez.Tudo dentro do loop funciona como esperado, e os dados são salvos corretamente o banco de dados--mas eu não consigo descobrir por que o loop não será executado novamente.Eu sei que se eu colocar uma chamada de método em função de retorno de chamada assíncrono ele vai funcionar bem, assim, talvez eu estou faltando alguma coisa sobre como assíncrono obras.Eu acho que o loop deve ser a pilha de chamadas, então, quando assíncrono é feito, o ciclo deve continuar, mas isso obviamente não é o caso.

Código completo:

for (var retstart = 0; retstart < elsvr_count; retstart += elsvr_retSize) { 

var elsvr_resultChunk;

async.series(
    [ 
        function(callback){

            var elsvr_Query = String(elsvr_baseURL) + "apiKey="+ String(elsvr_apiKey) + "&query=af-id(" + String(elsvr_ID) + ")&httpAccept=application/" + String(elsvr_resultType) + "&count=" + String(elsvr_retSize) + "&view=";

            $.get(elsvr_Query, function(result) {

                elsvr_count = parseInt(result["search-results"]["opensearch:totalResults"]); //the number of results
                console.log("count set at " + elsvr_count);
                elsvr_resultChunk = result["search-results"]["entry"]; //the current chunk of the total result, the size of which elsvr_retSize
                callback(null);
            });//end get

        },

        function(callback){

            async.eachSeries(elsvr_resultChunk, function(item, callback){
                var docQuery = item["prism:url"] + "?apiKey=" + String(elsvr_apiKey) + "&httpAccept=application/" + String(elsvr_resultType);

                $.ajax({
                    url: docQuery,
                    type: 'GET',
                    dataType: 'json',
                    success: function(result){
                        elsvr_results.push(result);
                        return callback(null);
                    },
                    error: function(err){
                        console.log("error returned: "+err.statusText);
                        elsvr_errors = elsvr_errors+1;
                        return callback(null);
                    }
                });
            },

            function(err, results) {
                if (err) console.log("error: " + err);
                else
                    callback(null, elsvr_results);
            });

        }
    ],

    //callback from async.series
    function (err, results){
        if (err)
            console.log("ERROR: " + JSON.stringify(err));
        else {
            db.getDoc('unprocessed', function(er, doc){
                if (er) throw new Error(JSON.stringify(er));

                if (doc.elsvr != undefined)
                    doc.elsvr = _.extend(results[1], doc.elsvr);
                else
                    doc.elsvr = results[1];

                db.saveDoc('unprocessed', doc, function(er, ok) {
                    if (er) throw new Error(JSON.stringify(er));
                    console.log('saved a chunk to the database: ' + db.name);
                });
            });
        }
     }
);//end async.series
}//end for loop
Foi útil?

Solução

Ok, eu finalmente resolvido.Acontece que o loop foi não executar de forma síncrona, e desde que eu atualizar o loop condicional (elsvr_count) dentro da série assíncrona, o ciclo foi concluído antes da condicional, na verdade, foi definido corretamente.No entanto, esse não era o único problema--se eu removido condicionais atualização e simplesmente definir elsvr_count ser um número alto, fora do loop, o loop seria ainda antes de executar de forma assíncrona assíncrona série devolvidos.

Eu vou postar a minha solução no caso de qualquer outra pessoa, é executado em um problema semelhante:Basicamente, substituir o loop for com um assíncrono.enquanto o ciclo da seguinte forma

        async.whilst(function() { return retstart < elsvr_count; }, 
            function(callback) {
                var elsvr_resultChunk;
                async.series(

                      //...
                      //same stuff as above goes here
                      //...

                      //save the document to the database
                      db.saveDoc('unprocessed', doc, function(er, ok) {
                          if (er) throw new Error(JSON.stringify(er));
                          retstart += elsvr_retSize; //<-- to replace the increment of the for loop
                          callback(null); //<-- important     
                      });

                      //...
                      //...
                );//end async.series
            },

           //callback for the whilst loop. this will be called once the condition is no longer met (retstart < elsvr_retSize)
           function(err) {
               //do stuff in here
           }
        );//end async.whilst
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top