Stop running a JavaScript function to perform another function

1

I'm developing a system using angular and have the following function:

    function drawLatLong(i, arrayIdColetor) { 
.....
         (não exibi o código por ser grande e achar desnecessário que vcs o analisem)
.....
      });

This function is invoked in a for:

for(var j = 0; j < $kinvey.arrayIdColetor.length;  j++){
   drawLatLong(j, $kinvey.arrayIdColetor);          
 }

The drawLatLong function, which is invoked N times according to FOR, takes a considerable amount of time to execute because it does relatively heavy queries in the database.

The problem I'm having is that if the user invokes another function without the drawLatLong function has ended, the system does not behave as it should.

Would you have any way to keep this situation under control? That is, does it only allow the user to execute another function after the drawLatLong has been finalized? Or would it be possible to break the drawLatLong function in the middle if another function is invoked by the user?

I hope I have been clear. Thanks in advance.

    
asked by anonymous 14.12.2015 / 18:02

3 answers

1

You can use a callback so that the next "for" is only executed at the end of drawLatLong .

function drawLatLong(i, arrayIdColetor, callback) { 
    .....
    (não exibi o código por ser grande e achar desnecessário que vcs o analisem)
    .....
    callback(); 
};

In place of for you can use a function that will be "called" (executed) as soon as drawLatlong finishes.

function callFor(j, arrayIdColetor) {
  if (j < arrayIdColetor.length)
    drawLatLong(j, arrayIdColetor, function() {
      callFor(j + 1, arrayIdColetor)
    });
}
callFor(0, $kinvey.arrayIdColetor);

Here is a demo (with change proposed in the comment):

    var $kinvey = {
      arrayIdColetor: [5, 12, 124, 636, 47, 45]
    }

    function addEl(txt) {
      var li = document.createElement('li');
      li.innerHTML = txt;
      document.getElementById('demo').appendChild(li);
    }

    function add400(callback) {
      addEl(400);
      callback();
    }

    function drawLatLong(i, arrayIdColetor, callback) {
      addEl(arrayIdColetor[i]);
      setTimeout(function() { //faz uma execução assíncrona
        add400(function() {
          setTimeout(function() { //faz outra execução assíncrona
            //esse callback() foi passado como parâmetro da função "drawLatLong"
            callback();
          }, 1000);
        });
      }, 1000);
    };

    function callFor(j, arrayIdColetor) {
      if (j < arrayIdColetor.length)
        drawLatLong(j, arrayIdColetor, function() {
          callFor(j + 1, arrayIdColetor)
        });
    }
    callFor(0, $kinvey.arrayIdColetor);
<ul id="demo"></ul>
    
14.12.2015 / 19:04
1

To do this you'll need to use .promisse () . With it you can do asynchronous programming with javascript.

See this example

$( "button" ).on( "click", function() {
  $( "p" ).append( "Started..." );

  $( "div" ).each(function( i ) {
    $( this ).fadeIn().fadeOut( 1000 * ( i + 1 ) );
  });

  $( "div" ).promise().done(function() {
    $( "p" ).append( " Finished! " );
  });
});
    
14.12.2015 / 18:12
0

Would a simple IF condition solve the problem?

var executandoAcao = function () {
 for (var j = 0; j < $kinvey.arrayIdColetor.length;  j++) {
   drawLatLong(j, $kinvey.arrayIdColetor);          
 }
return true;
}();

if (executandoAcao) {
      outrafuncao();
}

If you want to break in the middle of the loop, doing so also works:

 function executandoAcao(interromper) {

     for (var j = 0; j < $kinvey.arrayIdColetor.length;  j++) {
             drawLatLong(j, $kinvey.arrayIdColetor);
          if (interromper) {
             break;
          }          
     }
    return true;
 }

 var interromper = (outraFuncao) ? true : false;
 executandoAcao(interromper);

 var outraFuncao = function() {
     var promise = false;
     //aqui a outra função que vc quer executar
     $('#elemento').on('click', function() {
         promise = true;
     });
 return promise;
 }();
    
14.12.2015 / 19:04