2012-02-01 1 views
7

Je voudrais ajouter un délai de 1-2 secondes à chaque itération de la boucle suivante.comment ralentir une boucle javascript

<html> 
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 

<input id="start" type="submit"> </input> 
<div id='status'></div> 

<script> 
var geocoder=new google.maps.Geocoder();     
var glGeocodeCount = 0 ; 

$(document).ready(function() { 

    $('#start').click(function() { 

     //srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2");  

     for(x=0;x<20;x++){ 
      srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2"); 
     } 
     return false; 
    });   
}); 

function srPerformGeocode(address){  
    if (geocoder){     
     geocoder.geocode({ 'address': address }, function (results, status) {                    
      if (status == google.maps.GeocoderStatus.OK){                                           
       $('#status').prepend("Success : " + address + "<br/>"); 

      } 
      else{ 
       $('#status').prepend("Failed : " + address + "<br/>"); 

      } 
     }); 
    } 
} 
</script> 
+0

Pourquoi géocodez-vous la même adresse 20 fois? – ceejayoz

+0

à titre d'exemple. J'ai remarqué que certains fournisseurs d'API (comme Google) n'aiment pas que vous frappiez trop souvent à leur porte. Je voudrais réduire la fréquence de l'appel en utilisant une minuterie, mais j'ai du mal à l'utiliser dans une boucle, –

+0

C'est vrai, mais pourquoi voudriez-vous frapper à leurs portes avec la même demande à chaque fois? – ceejayoz

Répondre

11

Vous pouvez le faire de cette façon avec setTimeout():

$(document).ready(function() { 
    $('#start').click(function() { 
     //srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2");  
     var x = 0; 

     function go() { 
      srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2"); 
      if (x++ < 20) { 
       setTimeout(go, 2000); 
      } 
     } 
     go(); 

     return false; 
    });   
}); 

Cela ne me fait me demande pourquoi vous faites une recherche de géocodage sur l'adresse exacte même 20 fois de suite?

+0

mr friend - s'il vous plaît voir ci-dessus –

4

Vous voudrez probablement utiliser une minuterie pour cela. Si vous insérez simplement une boucle de retard dans le code, le résultat sera seulement que le code prend plus de temps à s'exécuter, mais le résultat final s'affichera tout de suite après la fin du code.

Vous pouvez utiliser les méthodes setTimeout ou setInterval. Exemple:

function(){ 

var instructions = [ 
function() { /* do something */ }, 
function() { /* do something */ }, 
function() { /* do something */ }, 
function() { /* do something */ } 
]; 

var index = 0; 

var handle = window.setInterval(function() { 
if (index < instructions.length) { 
    instructions[index++](); 
} else { 
    window.clearInterval(handle); 
} 
}, 10); 

}(); 
0

J'ENCOURAGER de se débarrasser de la boucle et en utilisant setTimeout:

$('#start').click(function() { 
     var i = 0, max = 20, delay = 2000, run; 
     run = function(){ 
      srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2"); 
      if(i++ < max){ 
       setTimeout(run, delay); 
      } 
     } 
     run(); 
     return false; 
    }); 
0

J'ai un sentiment que vous préférez ne pas commencer la prochaine itération de la boucle jusqu'à ce que la recherche de géocodage est vraiment complète. Ainsi, le mot-clé là est "callback":

au lieu du for..., faites ci-dessous. Je sais que ce n'est peut-être pas quelque chose que vous connaissez, mais essayez de le comprendre (ça devrait marcher).

var dogeo = function(callback) 
{ 
    srPerformGeocode("address", callback); 
}; 

var counter = 0; 

var geoCallback = function() 
{ 
     counter++; 

     if(counter < 20) 
     { 
      dogeo(geoCallback); 
     } 

}; 


dogeo(geoCallback); 



function srPerformGeocode(address, callback){  
    if (geocoder){     
     geocoder.geocode({ 'address': address }, function (results, status) {  


      // this function is a callback of geocode() 

      if (status == google.maps.GeocoderStatus.OK){                                           
       $('#status').prepend("Success : " + address + "<br/>"); 

      } 
      else{ 
       $('#status').prepend("Failed : " + address + "<br/>"); 

      } 

      callback(); // let the caller know this is done 
     }); 
    } 
} 
+1

Pause en utilisant setTimeout/setInterval peut tout fonctionner pour vous, mais c'est une illusion. Si je peux lire votre code correctement, le problème d'origine est que votre boucle est plus rapide que geocoder.geocode revient à chaque fois. Ainsi, la seule façon de ne pas avoir d'appels de géocodage parallèles serait d'attendre que l'on ait terminé avant que le suivant ne soit lancé. Cela dit, il n'y a pas besoin de ralentir davantage la boucle - si tout ce que vous essayez d'éviter, ce sont des appels parallèles. Si vous souhaitez toujours faire une pause entre les appels, vous devez toujours utiliser les rappels en combinaison avec setTimeout. –

+0

Oui, j'aimerais éviter les appels parallèles et ralentir la boucle. Il ne semble pas possible de faire de google api pour agir de manière synchrone, donc je dois tout empiler dans leurs succès. Je vais essayer de comprendre votre code ... –

+0

ce qui précède élimine les appels parallèles; pour faire une pause entre les appels, faites ceci: 'si (compteur <20) { window.setTimeout (function() { dogeo (geoCallback); } }, 2000);' –

Questions connexes