javascript loop with sleep [duplicate]

4

How would you make a or any loop type show the result respecting the time of 1 second for example between one iteration and another?

I tried this and it did not work:

for( var i=0; i < 10; i++ ){
    setTimeout(function (){console.log('valor de i='+i); },1000);
}

The purpose of these ranges is in the following situation:

dup.crtPdf=function(flag){    
    var array = $('#dup-jqxGrid02').jqxGrid('getrows');                          
    dup.arrayCrt = array.slice(0);                                               
    var tempo =0;
    for(var i=0; i<array.length; i++){                                  
            var obj = new Object();                  
            switch (flag){
                case 1: obj.ireport = "/reports/samples/crt_frete_pago_completo"; break; // CASO FOR IGUAL A 1 - FRETE PAGO
                case 2: obj.ireport = "/reports/samples/crt_a_pagar_completo"; break;    // CASO FOR IGUAL A 1 - FRETE À PAGAR
            }            
            obj.parametros = new Array({"id" : dup.arrayCrt.pop().con_id });
            custom.ajax(obj,'registrar',"../relatorios/imprimir.php");
            window.open("../relatorios/imprimir.php");                                          
    }               
};

File print.php

    <?php    
    /* @author Maison K. Sakamoto
     * Data: 20/09/2013
     * @version 0
     * Arquivo Generico para imprimir quaisquer iport 
     * 
     * COMO USAR:
     * 1º FAZER UMA CHAMADA PARA A FUNÇÃO REGISTRO
     *      DEVERA FAZER UM POST VIA AJAX COM UM OBJETO CONTENDO DOIS PARAMETROS
     *      PARAMETRO 1 - STRING CONTENDO O PATH/NOME DO ARQUIVO.JRXML
     *      PARAMETRO 2 - ARRAY DE PARAMETROS NECESSÁRIOS PARA O JRXML FAZER A CONSULTA NO BANCO DE DADOS
     * 2º NO RETORNO DO AJAX(success) DEVERÁ SER FEITO UM "window.open()" CHAMANDO ESTE ARQUIVO
     */
    include_once 'server/Adl/Configuration.php';
    include_once 'server/Adl/Config/JasperServer.php';
    include_once 'server/Adl/Config/Parser.php';
    include_once 'server/Adl/Integration/RequestJasper.php';
    @session_start();                                                           //ABRE AS VARIAVEIS DE SESSÃO
    @$funcao = $_REQUEST['funcao'];                                             //PEGANDO O NOME DA FUNÇAO 
    is_string($funcao) ? call_user_func($funcao) : imprimir();                  //VERIFICA SE É UM REGISTRO OU IMPRESSÃO    
    function imprimir(){                                                        //FUNÇÃO IMPRIMIR        
        $obj = (object) unserialize($_SESSION['obj']);                          //PEGANDO DA SESSION E PARSE EM OBJECT                
        $jasper = new Adl\Integration\RequestJasper();                          //INSTANCIA DA API JASPERSERVER        
        header('Content-type: application/pdf');                                //CABEÇALHO SETANDO TIPO PDF
        echo $jasper->run($obj->ireport,'PDF',$obj->parametros[0]);             //EXECUÇÃO        
    }                                                                           //FIM DA FUNÇÃO IMPRIMIR
    function registrar(){                                                       //FUNCÃO REGISTRA OS PARAMETROS EM SESSÃO
        $_SESSION['obj'] = serialize($_REQUEST['obj']);                         //OBJETO COM ATRIBUTO "IREPORT" E "PARAMETROS"        
        echo json_encode(Array("info"=>"ok"));                                  //RETORNO DE CONFIRMAÇãO DO AJAX        
    }                                                                           //FIM DA FUNÇÃO REGISTRAR        
?>

In other words, custom.ajax(obj,'registrar',"../relatorios/imprimir.php"); registers in $_SESSION and then I open the file print.php with window.open("../relatorios/imprimir.php"); so this file is generic and can be used several times by changing only the parameters in ajax, indicating which iReport will be called

    
asked by anonymous 19.01.2016 / 19:42

6 answers

7

Hello, you can use this way,

 var i = 0;
 var loop = setInterval(function(){ 
   console.log("valor de i="+i); 
   if(i == 10){
      clearInterval(loop);
   }
   i++;
 }, 1000);
    
19.01.2016 / 19:48
5

You can combine a closure with a setInterval , so that it works similarly to a while

(function () {
  var indice = 0;
  var limite = 10;
  
  var interval = setInterval(function (){
    console.log('valor de indice=' + indice); 
    
    indice++;
    if (indice == limite) {
      clearInterval(interval);
    }
  },1000);
})();

Here is an alternative inspired by Parallel.For of C# , in this case I have a function to manage for .

var _for = function (fromInclusive, toExclusive, callback){
  var indice = fromInclusive
  var interval = setInterval(function () {
    callback(indice);
    indice++;
    if (indice == toExclusive) {
      clearInterval(interval);
    }
  }, 1000);
}

_for(0, 10, function (i) {
  console.log("valor de i = " + i);
});
    
19.01.2016 / 19:48
2
for( var i=0; i < 10; i++ ){
    setTimeout(function (){console.log('valor de i='+i); },i*1000);
}
    
19.01.2016 / 19:46
1

You already have good answers on how to do this with setInterval so I will not go that way.

You can create a function to wait for the desired period and call it after each loop, like this:

for( var i=0; i < 10; i++ ){
   console.log('valor de i='+i); 
	 aguarde(1000);
}

function aguarde(ms){
   var inicio = new Date().getTime();
   var fim = inicio;
   while(fim < inicio + ms) {
     fim = new Date().getTime();
  }
}

Source: Javascript - Wait 5 seconds before executing next line

    
19.01.2016 / 19:53
1

Alternative with SetTimeout () :

var setTimeOut = (function(){
    var callback = null;
    var time = null;
    var iterate = null;

    if(!!iterate) iterate = 1;
    if(!!time) time = 1;

    var k = 1;
    var loop = function(){
        setTimeout(function(){
            if(typeof(callback) == 'function')
                callback(k);
            if(k < iterate){
                loop();
                k++;
            }
        }, time)
    };

    return function(c, t, i){
        callback = c;
        time = t;
        iterate = i;
        loop();
    }
})();
setTimeOut(function (i){console.log('valor de i='+i); },1000, 5)
    
19.01.2016 / 20:23
1

I'll explain how to do with setTimeout when explaining why Rodrigo's method made i worth 10 every time.

setTimeout is an asynchronous call. This means that by the time the first setTimeout fired the received function, the loop had already done its 10 iterations a long time ago. The variable i received as a parameter by the function is only a reference, and this reference already has the value 10, since that is the value of it in the last iteration of the loop. The variable i remains alive as long as a function has a reference to it, and in that case, several functions still have it.

How do I resolve this?

for(var i = 0; i < 10; i++){

    (function(indice) {
        setTimeout(function() {
            console.log("Valor de i=" + indice)
        }, indice*1000)
    })(i); // uma chamada de função ocorre aqui, fixando o valor de indice para a função interna

}

This works because, at each iteration, a function is in fact called and not just defined. The parameter value is evaluated at the time of the pass and not at the time of the function definition.

    
19.01.2016 / 20:31