Exit the loop suddenly

Asked

Viewed 156 times

2

Let’s imagine the following code:

function FazAlgoTrabalhoso(parametro1, parametro2, parametro3){
//Algo trabalhoso aqui
}

var i;
for(i=0;i<=coisas.length;i++){
  //"coisas" é um array já preenchido
  FazAlgoTrabalhoso(coisas[i].algo1, coisas[i].algo2, coisas[i].algo3);
}

$( "#botao_para_cancelar" ).click(function() {
  //Algo para cancelar...
});
  • Let’s say the "things" array has 100 positions, so the loop for goes run 100 times, ie will make "something laborious" 100 times.
  • Let’s also consider that "Fazalgotrabalhoso" takes about 5 seconds to fully execute.

My question is: How to manage the cancellation of "Fazalgotrabalhoso"? For example, if it has run 50 times, how to cancel subsequent runs via a button? I did not succeed in my attempts and it always ends up running the whole loop....

  • if ( condition ) Return

  • I think the problem is in the loop for. Even if you have a Return inside the function, the for has already "ordered" the 100 runs and it ends up passing...

3 answers

2

Your biggest problem is that...

var i;
for(i=0;i<=coisas.length;i++){
  FazAlgoTrabalhoso(coisas[i].algo1, coisas[i].algo2, coisas[i].algo3);
}

...is a process synchronous, which means that Javascript will not stop to check if an event has been triggered, such as clicking a button.

You need to convert this function to operate asynchronously:

function FazAlgoTrabalhosoAsync(x) {
  if (!x) x = 0;

  FazAlgoTrabalhoso(coisas[i].algo1, coisas[i].algo2, coisas[i].algo3);

  if (x < coisas.length) 
      setTimeout(function() {FazAlgoTrabalhosoAsync(x + 1);}, 1);
}

FazAlgoTrabalhosoAsync();

setTimeout() causes the function to be called in the future. In the meantime, events can be intercepted, and an interrupt flag marked as true:

var tenhoQueParar = false;

$( "#botao_para_cancelar" ).click(function() {
  tenhoQueParar = true;
});

function FazAlgoTrabalhosoAsync(x) {
  if (!x) x = 0;

  FazAlgoTrabalhoso(coisas[i].algo1, coisas[i].algo2, coisas[i].algo3);

  if ((x < coisas.length) && !tenhoQueParar) 
      setTimeout(function() {FazAlgoTrabalhosoAsync(x + 1);}, 1);
}

FazAlgoTrabalhosoAsync();
  • Hmm, I guess that’s where I’m going wrong... so I’ll test... Just one question: correct me if I’m wrong, but I think where you say "Synchronous" would be "Asynchronous" and vice versa, right? Because if my function were asynchronous, I mean, if I waited for the previous result to continue, I think it would work... Correct me if I’m wrong. Thank you for the great answer :)

  • I believe the terms are correct, @Pedroantônio - an asynchronous function is out of sync, meaning it does not wait.

  • Yes, @Onosendai, is that you said that my function is synchronous... and in my view, she is not waiting for the previous result...

  • @Pedroantônio Nop, I said the process is synchronous. Between the loop provided by for and sequential function calls FazAlgoTrabalhoso there is no space for other events to happen. Sequential calls occur synchronously, in this case.

0

I decided as follows:

    function FazAlgoTrabalhoso(parametro1, parametro2, parametro3){
    //Algo trabalhoso aqui

    var timer = window.setInterval(function(){
    var pagina = $$('.page').data('page');
    console.log("Estou na página: "+pagina);
    if(pagina != 'preview'){
        //Rotina de cancelamento...

        console.log('Abortado');
        clearInterval(timer);
    }
 },1000);
}

That is, I changed the scope. Instead of canceling at the click of a button, I was able to monitor when the user leaves the page. In this, I cancel the process.

-1

To exit the loop just add the break

var cancelar = false;
function FazAlgoTrabalhoso(parametro1, parametro2, parametro3){
//Algo trabalhoso aqui
}

var i;
for(i=0;i<=coisas.length;i++){
  //"coisas" é um array já preenchido
  FazAlgoTrabalhoso(coisas[i].algo1, coisas[i].algo2, coisas[i].algo3);
  if (cancelar){
      break;
  }
}

$( "#botao_para_cancelar" ).click(function() {
  cancelar = true;
});
  • But in my case, the interruption of the loop would have to be through the click on a button - that could occur at any time, IE, the loop probably already traveled....

  • I edited the question with the "cancel button"

  • change the variable, Count = 0; cancel = false; where when you click the cancel button it puts cancel = true;

Browser other questions tagged

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