Knowing @bfavaretto I know that he used a didactic way to solve the problem and explain in a simple way how JS works. I will try to be a little more technical here I directly answer the question of the user @Alexandre C.Caus.
Javascript runs on only one thread, but functions as setTimeout
will be executed late without stopping the execution of the function that executed the call. That is, the loop will be fully executed and the setTimeout
shall be lined up after the execution, awaiting the time of the point at which they were called.
For a code to be called after 10 seconds in sequence, the setTimeout
should be "within" of the execution of the previous.
Because this process generates many functions within each other, the code can get very messy, to simplify a little the answer I will employ the use of jQuery’s own promises, to simplify the code:
var promisse;
var waitFor = 10e3; // 10 segundos
$(grupo).each(function(i){
function ajaxCall(i) {
return $.ajax({
url: "curltst.php",
data: {
acao: "teste",
mensagem: mensagem,
grupo: grupo[i]
},
dataType: "xml",
method: "POST",
success: function (data) {
grupo = $(data).find("tdgrupo").text();
status = $(data).find("tdstatus").text();
$("tbody").append("
<tr>
<td>" + grupo + "</td>
<td>" + status + "</td>
</tr>");
},
error: function () {
alert("ERRO 008");
}
});
}
// Na primeira requisição use a promessa diretamente do retorno do
// método ajax, isso vai fazer com que a primeira requisição seja
// instantânea.
if(!promisse) promisse = ajaxCall(i);
// Caso já seja uma promessa, a função de callback vai ser chamada
else promise.then(function(){
// Definimos a deferencia da promessa que irá aguardar o tempo
// desejado aqui, e já retornamos a nossa sequencia de promessas
// antes dela ser resolvida, assim o loop segue fazendo o mesmo
// até chegar ao fim.
var deferred = $.deferred();
// Isso será executado apenas quando a promessa anterior for resolvida
// isso é, você tem o resultado da sua ultima requisição ajax e
// agora vai esperar o tempo necessário pra proxima requisição
setTimeout(function(){
// Passado tempo, agora vamos fazer a nova requisição
// e vamos fazer uma ponte do resultado da requisição a nossa
// promessa, assim o proximo só começa ser executado quando
// a resposta chegar
ajaxCall(i).done(deferred.resolve).fail(deferred.fail);
}, waitFor);
return deferred.promise();
});
});
How would the execution flow of this code:
- variable for promises is defined in scope
- Loop is started
- check if there are promises, or do the prepares the request and save promise (the request will be executed later), goes to the next loop result;
- if there’s promise, prepares setTimeout to return a promise that contains the AJAX request and puts it in the promise queue, then goes to the next loop result;
- Finished the loop;
- First AJAX request executed, when return;
- Initiating
setTimeout
10 seconds, when finished;
- Start next AJAX request, and when finished, repeat the process of the previous step until all promises are resolved;
More details: http://answall.com/questions/51268/qual-a-diferença-entre-comunicação-ass%C3%Adncrona-e-s%C3%Adncrona/51269#51269, http://answall.com/questions/16950/como-programming-ass%C3%Adncrona-funciona-em-javascript
– bfavaretto
Bah! I thought that setTimeout locks the script by the time I estimated until the processing of the function it contained, as php Sleep() does.
– Ale
but it wouldn’t make sense from there, because it would compromise the rest of the script that comes later, but his job is just to estimate a time, delay the function. Valeu @bfavaretto!
– Ale
It’s not like that. Ajax isn’t like that either, it’s the same principle n
– bfavaretto
Look at that, before I add the
*i
in the 10000, was sending right the group array:grupo = ["951179678239911","1559692210955385","860177374023863","722424877870676"]
, now, I added this (only this change), and at some point the group[i](in the second) just returning me the value 1, and the 4(last) I just return 9, then when I take the*i
indices correspond to the value right, this can be by what? for me makes no less sense, in fact I find nothing to even see..– Ale
the interesting thing is that, although after the 9511 came 1559 the order that happens is 9511.. then comes 1, then 1559.. after last 9. that is, the indices of 860177.. and 72242.. are not sent with the correct value and still outside the array order..
– Ale
You change this array of groups somewhere after this code?
– bfavaretto
change no, just send to curltst.php the group by the POST method using AJAX, and there in curltst.php I do the procedures with the group, it happens that in the request what is being posted is of disagreement with what was to be, the values of the array is correct(as I showed above, it is exactly what is in the group array), it was to be 72242.. and it’s going 9, now I tested again with the team
10000*i
(before it was30000*i
) and sometimes not even send the group(as if the group[i] was empty)..– Ale
I don’t know what it could be. See a proof of concept that this structure works.
– bfavaretto
according @bfavaretto, great response, must be something then that went unnoticed, obg by the attention!
– Ale
Well, I’ve included another way, if you want to test.
– bfavaretto
By the way, I found the cause of your problem: you redefine
grupo
within the Success, avar
there.– bfavaretto
perfect @bfavaretto, that was exactly the mistake, now everything is ok, thanks for the force, I was going to skate in it a while because this variable of global and local had not even passed in the head.. all the best for you there master! :)
– Ale
This solution does not seem right to me. what I understand is that @Alexandrec.Caus wants to make the requests after 10 seconds and not put the results in the DOM after 10 seconds. Where in the case is making all requests immediately but waiting 10 seconds to persist.
– Gabriel Gartz
@Gabriel it is true that the code above (which was my second suggestion to him) works as you said. But I’m not so sure that this would be a problem for what it wants. It might be, it might not be. In fact I missed explaining what the code does.
– bfavaretto
I understand the motivation and agree with your answer, but aiming at the best learning I made an answer that exactly matches the result expected by the question. Unfortunately it’s more complex, but I think it can help other people who have the same question but are not satisfied with your answer which is specific to the @Alexandrec.Caus user
– Gabriel Gartz
Great @Gabrielgartz, +1 in your answer. In fact it’s the "right" way to do it. You surmised well, I went the easy way for considering that it would be easier for Alexandre to understand.
– bfavaretto