Knowing @bfavaretto I know he used a didactic way to solve the problem and explain in a simple way how JS works. I'll try to be a bit more technical here, I'll answer the question directly from the user @Alexandre C.Caus.
JavaScript runs on just one thread , but functions like setTimeout
will run late without stopping the execution of the function that ran the call. That is, the loop will be fully executed and the setTimeout
will be queued after execution, waiting for the time from the point where they were called.
For a code to be called after 10 seconds in sequence, the subsequent setTimeout
must be "inside" of the previous execution.
Because this process generates many functions one inside the other, the code can get very messy, to simplify the answer a bit I will employ the promises of jQuery itself, 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 flow of this code be:
- variable for promises is defined in scope
- Loop starts
- check for promises, otherwise make the prepare the request and keep promise (the request will be executed later), go to the next loop result;
- If there is a promise, prepares the setTimeout to return a promise that contains the AJAX request and puts it in the promises queue, then goes to the next loop result;
- Finished the loop;
- First AJAX request is executed, when to return;
- Starts
setTimeout
10 seconds when finished;
- Start the next AJAX request, and when done, repeat the process from the previous step until all promises are resolved;