web-dev-qa-db-fra.com

Attendez 5 secondes avant d'exécuter la ligne suivante

La fonction ci-dessous ne fonctionne pas comme je le souhaite. être novice en JS, je ne comprends pas pourquoi.

J'ai besoin d'attendre 5 secondes avant de vérifier si la newState est -1.

Actuellement, ça n’attend pas, ça vérifie tout de suite.

function stateChange(newState) {
  setTimeout('', 5000);

  if(newState == -1) {
    alert('VIDEO HAS STOPPED');
  }
}
240
copyflake

Vous devez mettre votre code dans la fonction de rappel que vous fournissez à setTimeout:

function stateChange(newState) {
    setTimeout(function () {
        if (newState == -1) {
            alert('VIDEO HAS STOPPED');
        }
    }, 5000);
}

Tout autre code sera exécuté immédiatement.

273
Joseph Silber

Vous ne devriez vraiment pas faire cela, l'utilisation correcte du timeout est le bon outil pour résoudre le problème du PO et pour toute autre occasion où vous souhaitez simplement exécuter quelque chose après un certain temps. Joseph Silber l'a bien démontré dans sa réponse. Cependant, si dans certains cas de non-production vous vraiment voulez bloquer le fil principal pendant un certain temps, cela fais le.

function wait(ms){
   var start = new Date().getTime();
   var end = start;
   while(end < start + ms) {
     end = new Date().getTime();
  }
}

Avec exécution sous la forme:

console.log('before');
wait(7000);  //7 seconds in milliseconds
console.log('after');

Je suis arrivé ici parce que je construisais un scénario de test simple pour séquencer une combinaison d'opérations asynchrones autour d'opérations de blocage de longue durée (c'est-à-dire une manipulation DOM coûteuse) et il s'agit de mon opération de blocage simulée. Cela convient très bien à ce travail, alors j'ai pensé le publier pour toute autre personne qui arrive ici avec un cas d'utilisation similaire. Même dans ce cas, il crée un objet Date () dans une boucle while, ce qui risque de surcharger le catalogue général s'il est suffisamment long. Mais je ne saurais trop le souligner, cela ne convient que pour les tests, pour créer toute fonctionnalité réelle, vous devriez vous reporter à la réponse de Joseph Silber.

147
Mic

Voici une solution utilisant la nouvelle syntaxe async/wait .

Assurez-vous de vérifier support du navigateur car il s'agit d'une nouvelle fonctionnalité introduite avec ECMAScript 6.

Fonction d'assistance:

const delay = ms => new Promise(res => setTimeout(res, ms));

Utilisation:

const yourFunction = async () => {
  await delay(5000);
  console.log("Waited 5s");

  await delay(5000);
  console.log("Waited an additional 5s");
};

L'avantage de cette approche est que votre code ressemble et se comporte comme un code synchrone.

85
Etienne Martin

Utilisez une fonction de délai comme celle-ci:

var delay = ( function() {
    var timer = 0;
    return function(callback, ms) {
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
})();

Usage:

delay(function(){
    // do stuff
}, 5000 ); // end delay

Les crédits vont à l'utilisateur CMS, voir Comment retarder le gestionnaire .keyup () jusqu'à ce que l'utilisateur arrête de taper?

32
Kai Noack

Vous ne devriez pas simplement essayer de faire une pause de 5 secondes en javascript. Ça ne marche pas comme ça. Vous pouvez planifier l'exécution d'une fonction de code dans 5 secondes, mais vous devez insérer le code que vous souhaitez exécuter ultérieurement dans une fonction. Le reste de votre code continuera de s'exécuter immédiatement après cette fonction.

Par exemple:

function stateChange(newState) {
    setTimeout(function(){
        if(newState == -1){alert('VIDEO HAS STOPPED');}
    }, 5000);
}

Mais si vous avez un code comme celui-ci:

stateChange(-1);
console.log("Hello");

L'instruction console.log() s'exécutera immédiatement. La fin du délai d'attente dans la fonction stateChange() ne sera pas attendue. Vous ne pouvez pas simplement suspendre l'exécution de javascript pendant une durée prédéterminée.

Au lieu de cela, tout code que vous souhaitez exécuter avec du temps doit être à l'intérieur de la fonction de rappel setTimeout() (ou appelé à partir de cette fonction).

Si vous essayez de "mettre en pause" en boucle, vous devez "suspendre" l'interpréteur Javascript pendant un certain temps. Parce que Javascript n'exécute votre code que dans un seul thread, vous ne pouvez exécuter aucune autre opération en boucle (aucun autre gestionnaire d'événements ne peut être appelé). Ainsi, l'attente d'une modification d'une variable ne fonctionnera jamais car aucun autre code ne peut être exécuté pour modifier cette variable.

32
jfriend00

Si vous êtes dans un fonction asynchrone , vous pouvez simplement le faire en une seule ligne:

console.log(1);
await new Promise(resolve => setTimeout(resolve, 3000)); // 3 sec
console.log(2);

Remarque , si target est NodeJS, il sera plus efficace d'utiliser ceci (c'est une fonction setTimeout promisifiée prédéfinie):

await setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](3000) // 3 sec
18
Shl

Le meilleur moyen de créer une fonction comme celle-ci pour attendre en millisecondes, cette fonction attendra les millisecondes fournies dans l'argument:

function waitSeconds(iMilliSeconds) {
    var counter= 0
        , start = new Date().getTime()
        , end = 0;
    while (counter < iMilliSeconds) {
        end = new Date().getTime();
        counter = end - start;
    }
}
7

Essaye ça:

//the code will execute in 1 3 5 7 9 seconds later
function exec() {
    for(var i=0;i<5;i++) {
        setTimeout(function() {
            console.log(new Date());   //It's you code
        },(i+i+1)*1000);
    }
}
7
Steve Jiang

D'après Joseph Silber réponse , je le ferais comme ça, un peu plus générique.

Vous auriez votre fonction (créons-en une à partir de la question):

function videoStopped(newState){
   if (newState == -1) {
       alert('VIDEO HAS STOPPED');
   }
}

Et vous pourriez avoir une fonction d'attente:

function wait(milliseconds, foo, arg){
    setTimeout(function () {
        foo(arg); // will be executed after the specified time
    }, milliseconds);
}

A la fin vous auriez:

wait(5000, videoStopped, newState);

C'est une solution, je préférerais ne pas utiliser d'arguments dans la fonction wait (pour n'avoir que foo(); au lieu de foo(arg);) mais c'est pour l'exemple.

3
Sylhare

Je l'ai utilisé pour exécuter des jeux PC à partir de Edge ou IE. Et cela se referme automatiquement IE Edge après 7 secondes.

Firefox et Google Chrome ne peuvent pas être utilisés pour démarrer les jeux de cette façon.

<html<body>
<a href="E:\game\game.exe" name="game" onmouseout="waitclose(7000);"> game
<img src="game.jpg" width="100%" height="97%" ></a>
<script>
function waitclose(ms){
 var start = new Date().getTime();var end=start;
 while(end < start + ms) {end = new Date().getTime();}
window.open('', '_self', ''); window.close();
}
</script>
</body></html>
0
user4565320