Problems between loop and ajax

Asked

Viewed 487 times

2

Ajax

for (j=0; j < cidade_nome.length; j++) {
    $.post('envia.php', {ano:ano, ano2:ano2, cidade: cidade_nome[j].value}, fnRetorno);
}

Function fnReturn

function fnRetorno(retorno) 
{
    teste.push(retorno);
    console.log(j);
    if (j == cidade_nome.length) {
        soma(teste);
    }
}

Complete Code

function soma(teste) 
{
    console.log(JSON.parse(teste));
}

function fnRetorno(retorno) 
{
    teste.push(retorno);
    console.log(j);
    if (j==cidade_nome.length) {
        soma(teste);
    }
}

for (j=0;j<cidade_nome.length;j++) {
    $.post('envia.php', {ano: ano, ano2: ano2, cidade: cidade_nome[j].value}, fnRetorno);
}

Because ajax is asynchronous, the function fnRetorno calls the sum function, before the last ajax result is placed in the array teste.

Would have some way to ensure that the sum test function would only be called after ajax is run every time by loop?

  • SORRY, BUT YOU WANT HIM TO CALL AFTER EXECUTING ALL TIMES I MEAN... ONCE, OR EVERY TIME HE FINISHES EXECUTING THE REQUEST?

  • Let him call the sum function, just once. I guess I didn’t make it clear,

  • Explain better what you want to do with the request. What does the server do? What is the return?

  • The request returns to the fnRelat function a JSON that must be placed in the array,for the Sum function to be generated a graph.

  • But why run this request in a loop? Can’t you just pass the entire array at once and loop the server? For example: $.post('envia.php',{ano:ano,ano2:ano2,cidades:cidade_nome}, fnRetorno);

  • Then you can call the sum once after the for (and take it out of fnRetorno) and treat your array using $.each as you need it, isn’t that so? @Oeslei, your nomination is also quite interesting.

  • @Rafaelwithoeft This is not possible with an asynchronous request. The function would be executed before the return of the server.

  • 2

    @Oeslei Opa, sorry the slide did not remember this detail, well I only see two outputs, change the ajax to synchronous or send the logic to the server;

  • The idea of @Oeslei would work, but my city_name comes from:"var city_name = $('#city option:Selected');",I would need to turn into an even correct array?

  • @Rodolfooliveira Are you running a loop to traverse a string? Why?

  • @Oeslei is not a string, I am using a 'component' which is a checkbox combo,and city_name receives an object with the selected options

  • @Rodolfooliveira, you can then use something like $.each to scroll through its values forming an array and then send it to the server, or swap its component and let jquery take care of it for you example: var cidades = []; //Percorre tudo o que está selecionado em cidades $('#cidades :checked').each(function(i) { &#xA; cidades[i] = $(this).val(); &#xA;});

Show 7 more comments

3 answers

1

In your case, you can do something much simpler than what you’re doing, and avoid so many unnecessary posts, something like:

function soma(teste) 
{
    console.log(JSON.parse(teste));
}

function fnTest(data, pos) 
{
    teste.push(data, pos);
    if (pos==cidade_nome.length) {
        soma(teste);
    }
}

var data_post = {};
    for (var i in cidade_nome) {
         data_post[i] = {ano: ano, ano2: ano2, cidade: cidade:cidade_nome[i].value};
           fnTest(data_post[i], i);
        } 

    $.post('envia.php',data:data_post, function(rtn) {
          console.log(JSON.parse(rtn));
     });

And in PHP you do the treatment you need:

<?php
//captura a saída e veja o que retorna para fazer a tratativa 
var_dump($_POST['data']);
exit;

0

I believe the most correct approach in your case would be:

function fnRetorno(j) {

    if (j >= cidade_nome.length) return;

    $.post('envia.php', {..., cidade: cidade_nome[j].value}, function ()
    {
        // Não sei de onde vem a variável 'teste'
        soma(teste);

        fnRetorno(++j);
    })

};

fnRetorno(0);

In that case, you will call the next ajax call only when the previous one is closed.

Realize that the j has been passed by parameter. This helps decrease the pollution of the scope of your code, in addition to doing exactly the same thing desired in the for, which is to iterate until there is the element equivalent in cidade_nome.

0

Good morning Rodolfo try this way:

$.ajax({
    //função ajax
}).done(function () {
    //função após o ajax
});

This is another way, where you guarantee a call after the return of the ajax

Browser other questions tagged

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