2009-07-26 11 views
51

Je dois ajouter un délai d'environ 100 milisecondes à mon code Javascript mais je ne veux pas utiliser la fonction setTimeout de l'objet window et je ne veux pas utiliser une boucle occupée. Est-ce que quelqu'un a des suggestions?Mettre un retard en Javascript

+15

Pouvez-vous expliquer pourquoi setTimeout ne convient pas/ne répond pas à vos besoins? – eyelidlessness

Répondre

110

Malheureusement, setTimeout() est le seul moyen fiable (pas la seule façon, mais le seul moyen fiable ) pour mettre en pause l'exécution du script sans bloquer l'interface utilisateur.

Il est pas difficile à utiliser en fait, au lieu d'écrire ceci:

var x = 1; 

// Place mysterious code that blocks the thread for 100 ms. 

x = x * 3 + 2; 
var y = x/2; 

vous utilisez setTimeout() de réécrire cette façon:

var x = 1; 
var y = null; // To keep under proper scope 

setTimeout(function() { 
    x = x * 3 + 2; 
    y = x/2; 
}, 100); 

Je comprends que l'utilisation setTimeout() implique plus la pensée qu'un fonction souhaitable sleep(), mais malheureusement, le plus tard n'existe pas. Beaucoup de solutions de contournement sont là pour essayer de mettre en œuvre de telles fonctions. Quelques boucles en utilisant occupées:

function sleep(milliseconds) { 
    var start = new Date().getTime(); 
    for (var i = 0; i < 1e7; i++) { 
    if ((new Date().getTime() - start) > milliseconds){ 
     break; 
    } 
    } 
} 

autres using an XMLHttpRequest tied with a server script that sleeps for a amount of time before returning a result. Malheureusement, ce sont des solutions de contournement et sont susceptibles de causer d'autres problèmes (tels que la congélation des navigateurs). Il est recommandé de coller simplement avec la manière recommandée, qui est setTimeout()).

+2

J'utilise NoScript sur mon ordinateur portable précisément à cause de personnes qui utilisent des fonctions comme cette fonction de sommeil ou d'autres boucles serrées inutiles. Sinon, il brûle soudainement un trou sur mes genoux. –

+3

** @ James M.:** Totalement d'accord ... Je n'ai jamais compris pourquoi il y a un si grand stigmate autour de 'setTimeout()'. –

+2

Je ne crois pas que setTimeout() ait un quelconque stigmate qui l'entoure, c'est juste qu'il ne produit pas toujours l'effet désiré facilement. Dites, par exemple, si vous voulez faire tourner le processeur au ralenti pendant une courte période de temps dans une boucle de processus intensive pour éviter de bloquer le navigateur. L'obtention de ce résultat avec setTimeout peut être difficile pour les programmeurs JavaScript inexpérimentés. – KingRadical

2

This thread a une bonne discussion et une solution utile:

function pause(iMilliseconds) 
{ 
    var sDialogScript = 'window.setTimeout(function() { window.close(); }, ' + iMilliseconds + ');'; 
    window.showModalDialog('javascript:document.writeln ("<script>' + sDialogScript + '<' + '/script>")'); 
} 

Malheureusement, il semble que cela ne fonctionne pas dans certaines versions de IE, mais le fil a beaucoup d'autres propositions dignes si cela se révèle être un problème pour vous.

+2

On dirait une solution en attente d'un problème. Je ne peux pas penser à une seule situation dans laquelle 'setTimeout' ne ferait pas son travail. Mais +1 pour la créativité. :) –

3

En fait, seul le setTimeout convient à ce travail et normalement, vous ne pouvez pas définir des délais exacts avec des méthodes non déterminées comme des boucles occupées.

+0

Vous ne pouvez pas mettre en pause l'interpréteur js avec setTimeout. –

+0

Vous ne pouvez appeler une fonction qu'après un délai. setTimeout ne bloque pas. Le reste du code fonctionne comme il est censé le faire. –

11

J'ai juste eu un problème où j'avais besoin de résoudre cela correctement.

Via Ajax, un script reçoit des messages X (0-10). Ce que je voulais faire: Ajouter un message au DOM toutes les 10 secondes.

le code j'ai fini avec:

$.each(messages, function(idx, el){ 
    window.setTimeout(function(){ 
    doSomething(el); 
    },Math.floor(idx+1)*10000); 
}); 

En fait, penser aux délais d'attente en tant que "timeline" de votre script.

C'est ce que nous voulons code:

DoSomething(); 
WaitAndDoNothing(5000); 
DoSomethingOther(); 
WaitAndDoNothing(5000); 
DoEvenMore(); 

C'est COMMENT NOUS AVONS BESOIN DE LUI DIRE LE JAVASCRIPT:

At Runtime 0 : DoSomething(); 
At Runtime 5000 : DoSomethingOther(); 
At Runtime 10000: DoEvenMore(); 

Hope this helps.

+0

Merci pour la réponse expliquant le comportement de SetTimeOut. Le problème est que plus tard lorsque le code est long, ou dépend des réponses du serveur, il devient difficile de visualiser même le calendrier en quelques secondes. –

-5

Utilisez une fonction AJAX qui appellera une page php de façon synchrone, puis dans cette page vous pourrez mettre la fonction php usleep() qui agira comme un retard.

function delay(t){ 

var xmlhttp; 

if (window.XMLHttpRequest) 

{// code for IE7+, Firefox, Chrome, Opera, Safari 

xmlhttp=new XMLHttpRequest(); 

} 

else 

{// code for IE6, IE5 

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 

} 

xmlhttp.open("POST","http://www.hklabs.org/files/delay.php?time="+t,false); 

//This will call the page named delay.php and the response will be sent to a division with ID as "response" 

xmlhttp.send(); 

document.getElementById("response").innerHTML=xmlhttp.responseText; 

} 

http://www.hklabs.org/articles/put-delay-in-javascript

+4

s'il vous plaît formater le code pour le rendre lisible – kleopatra

+9

Ne pas oublier les bases de la conception de sites Web. Le principe fondamental est de réduire la charge du serveur autant que vous le pouvez. Pour une simple temporisation, vous demandez une page du serveur un nombre infini de fois. Pense juste à ce que tu fais ici. –

Questions connexes