Exemples de fonctions JavaScript setTimeout () –
   
 setTimeout  est une fonction JavaScript native (bien qu'elle puisse être utilisée avec une bibliothèque telle que jQuery, comme nous le verrons plus loin), qui appelle une fonction ou exécute un extrait de code après un délai spécifié (en millisecondes) ). Cela peut être utile si, par exemple, vous souhaitez afficher une fenêtre contextuelle après qu'un visiteur a parcouru votre page pendant un certain temps, ou si vous souhaitez un court délai avant de supprimer un effet de survol d'un élément (dans le cas où l'utilisateur accidentellement 

Cet article populaire a été mis à jour en 2020.
Exemple de base setTimeout
Pour illustrer le concept, la démo suivante affiche une fenêtre contextuelle, deux secondes après avoir cliqué sur le bouton.
Voir le stylo Modal Popup retardé magnétique par SitePoint ( @SitePoint ) sur CodePen .
Si vous ne voyez pas la fenêtre ouverte, veuillez visiter CodePen et y exécuter la démo.
Syntaxe
 Dans la documentation  MDN la syntaxe de  setTimeout  est la suivante:
 var timeoutID = scope.setTimeout (fonction [, delay, arg1, arg2, ...]);
var timeoutID = scope.setTimeout (fonction [, delay]);
var timeoutID = scope.setTimeout (code [, delay]);
où:
timeoutIDest un ID numérique, qui peut être utilisé en conjonction avec clearTimeout pour annuler la minuterie.scopefait référence à la fenêtre ou l'interface WorkerGlobalScope . La fonctionest la fonction à exécuter après l'expiration du temporisateur.le codeest une syntaxe alternative qui vous permet d'inclure un chaîne au lieu d'une fonction, qui est compilée et exécutée lorsque le temporisateur expire.retardest le nombre de millisecondes par lequel l'appel de fonction doit être retardé. S'il est omis, cette valeur par défaut est 0.arg1, ..., argNsont des arguments supplémentaires passés à la fonction spécifiée parfonction.
 Remarque: les crochets [] indiquent paramètres facultatifs. 
setTimeout vs window.setTimeout
 Vous remarquerez que la syntaxe ci-dessus utilise  scope.setTimeout . Pourquoi?
 Eh bien, lors de l'exécution de code dans le navigateur,  la portée  ferait référence à l'objet global  de la fenêtre .  setTimeout  et  window.setTimeout  font référence à la même fonction, la seule différence étant que dans la deuxième déclaration, nous référençons la méthode  setTimeout  comme propriété de la propriété  fenêtre  objet.
 À mon avis, cela ajoute de la complexité pour peu ou pas d'avantages. Si vous avez défini une autre méthode  setTimeout  qui serait trouvée et renvoyée en priorité dans la chaîne d'étendue, vous avez probablement de plus gros problèmes à vous inquiéter.
 Pour les besoins de ce didacticiel, Je vais omettre la fenêtre  mais en fin de compte, la syntaxe que vous choisissez dépend de vous.
Exemples d'utilisation
  setTimeout  accepte une référence à une fonction comme premier argument .
Cela peut être le nom d'une fonction:
 function salutation () {
  alerte ("Salut!");
}
setTimeout (salut, 2000);
Une variable qui fait référence à une fonction (une expression de fonction):
 const salutation = fonction () {
  alerte ("Salut!");
};
setTimeout (salut, 2000);
Ou une fonction anonyme:
 setTimeout (() => {alert ('Howdy!');}, 2000);
 Comme indiqué ci-dessus, il est également possible de passer  setTimeout  une chaîne de code à exécuter:
 setTimeout ('alert ("Howdy!");', 2000);
Cependant, ceci n'est pas conseillé pour les raisons suivantes:
- Il est difficile à lire (et donc difficile à maintenir et / ou à déboguer).
 -  Il utilise un 
eval implicitequi est un risque potentiel pour la sécurité. - Il est plus lent que les alternatives, car il doit invoquer l'interpréteur JS.
 
Cette question de dépassement de pile offre plus d'informations sur les points ci-dessus.
Passer des paramètres à setTimeout
 Dans un scénario de base, la méthode multi-navigateur préférée pour passer des paramètres à un rappel exécuté par  setTimeout  consiste à utiliser une fonction anonyme comme premier argument.
 Dans l'exemple suivant, nous sélectionnons un animal aléatoire dans un tableau  animaux  et passons cet animal aléatoire comme paramètre à une fonction  makeTalk . La fonction  makeTalk  est ensuite exécutée par  setTimeout  avec un retard d'une seconde:
 fonction makeTalk (animal) {
  bruits const = {
    chat: 'ronronner',
    chien: 'woof',
    vache: «moo»,
    porc: «oink»,
  }
  console.log (`Un $ {animal} va $ {bruits [animal]}.`);
}
fonction getRandom (arr) {
  retour arr [Math.floor(Math.random()*arr.length)];
}
animaux const = ['cat', 'dog', 'cow', 'pig'];
const randomAnimal = getRandom (animaux);
setTimeout (() => {
  makeTalk (randomAnimal);
}, 1000);
  Remarque: J'ai utilisé une fonction régulière ( getRandom ) pour renvoyer un élément aléatoire d'un tableau. Il serait également possible d'écrire ceci comme une expression de fonction en utilisant une fonction flèche: 
 const getRandom = arr => arr [Math.floor(Math.random()*arr.length)];
Nous passerons aux fonctions fléchées dans la section suivante.
Une méthode alternative
 Comme le montre la syntaxe  à la en haut de l'article il existe une deuxième méthode pour passer des paramètres à un rappel exécuté par  setTimeout . Cela implique de lister tous les paramètres après le délai.
En référence à notre exemple précédent, cela nous donnerait:
 setTimeout (makeTalk, 1000, randomAnimal);
 Malheureusement, cela ne fonctionne pas dans IE9 ou inférieur, où les paramètres apparaissent comme  non définis . Si vous n'êtes pas en mesure de devoir prendre en charge IE9, il existe  un polyfill disponible sur MDN .
 Le problème avec  ce 
 Code exécuté par  setTimeout  est exécuté dans un contexte d'exécution distinct de la fonction à partir de laquelle il a été appelé. Cela pose problème lorsque le contexte du  ce mot-clé  est important:
 const dog = {
  son: 'woof',
  écorce () {
    console.log (`Rover dit $ {this.sound}!`);
  }
};
aboiement();
// Sorties: Rover dit woof!
setTimeout (dog.bark, 50);
// Sorties: Rover dit non défini!
 La raison de cette sortie est que, dans le premier exemple,  ce  pointe vers l'objet  chien tandis que dans le deuxième exemple  ce  pointe vers le fenêtre globale  objet  (qui n'a pas de propriété de son  ).
Pour contrer ce problème, il existe différentes mesures…
 Définissez explicitement la valeur de  this 
 Vous pouvez le faire en utilisant  bind une méthode qui crée une nouvelle fonction qui, lorsqu'elle est appelée, a son  this  mot-clé défini sur la valeur fournie (dans notre cas, l'objet  chien ). Cela nous donnerait:
 setTimeout (dog.bark.bind (dog), 50);
  Remarque:  bind  a été introduit dans ECMAScript 5, donc ne fonctionnera que dans  navigateurs plus modernes . Vous pouvez en savoir plus à ce sujet (et sur d'autres méthodes de définition de la valeur de  this )  dans cet article SitePoint . 
Utiliser une bibliothèque
De nombreuses bibliothèques sont livrées avec une fonction intégrée fonctions pour résoudre ce problème. Par exemple, la méthode jQuery jQuery.proxy () . Cela prend une fonction et retourne une nouvelle qui aura toujours un contexte particulier. Dans notre cas, ce serait:
 setTimeout ($. Proxy (dog.bark, dog), 50);
Utilisation des fonctions fléchées avec setTimeout
Les fonctions fléchées ont été introduites avec ES6. Ils ont une syntaxe beaucoup plus courte qu'une fonction régulière:
 (param1, param2, paramN) => expression
 Vous pouvez, bien sûr, les utiliser avec  setTimeout mais il y a une chose à savoir – à savoir, que les fonctions fléchées n'ont pas leur  cette valeur . Au lieu de cela, ils utilisent la  cette  valeur du contexte lexical englobant.
En utilisant une fonction régulière:
 const dog = {
  son: 'woof',
  écorce () {
    console.log (`Rover dit $ {this.sound}!`);
  }
};
aboiement();
// Rover dit woof!
Utilisation d'une fonction de flèche:
 const dog = {
  son: 'woof',
  écorce: () => {
    console.log (`Rover dit $ {this.sound}!`);
  }
};
aboiement();
// Rover dit non défini!
 Dans le deuxième exemple, ce  pointe vers l'objet global  de la fenêtre  (qui encore une fois, n'a pas de propriété  sound ).
 This peut nous déclencher lorsque vous utilisez les fonctions fléchées avec  setTimeout . Auparavant, nous avons vu comment fournir une fonction appelée dans un  setTimeout  avec la bonne  cette  valeur:
 setTimeout (dog.bark.bind (dog), 50);
 Cela ne fonctionnera pas lorsque vous utilisez une fonction flèche dans la méthode  introduisez car la fonction flèche n'a pas sa propre valeur  cette . La méthode enregistrera toujours  undefined .
Code de nettoyage avec fonctions fléchées et setTimeout
 Cependant, comme les fonctions fléchées n'ont pas leur  cette valeur elle peut également fonctionner. à notre avantage.
Considérez un code comme celui-ci:
 const dog = {
  son: 'woof',
  delayBark () {
    setTimeout (
      fonction() {
        console.log (`Rover dit $ {this.sound}!`);
      }
      .bind (this)
    , 1000);
  }
}
dog.delayedBark ();
Il peut être réécrit de façon plus concise avec une fonction flèche:
 const dog = {
  son: 'woof',
  delayBark () {
    setTimeout (
      () => {console.log (`Rover dit $ {this.sound}!`); }, 1000
    );
  }
}
dog.delayedBark ();
Si vous souhaitez une introduction aux fonctions fléchées, veuillez lire « Fonctions flèches ES6: syntaxe grasse et concise en JavaScript ».
Annulation d'une minuterie
 Comme nous l'avons appris au début de l'article, la valeur de retour de  setTimeout  est un ID numérique qui peut être utilisé pour annuler la minuterie en conjonction avec la fonction  clearTimeout :
 const timer = setTimeout (myFunction, 3000);
clearTimeout (timer);
Voyons cela en action. Dans le stylet suivant, si vous cliquez sur le bouton Démarrer le compte à rebours un compte à rebours commencera. Si le compte à rebours se termine, les chatons l'obtiennent. Cependant, si vous appuyez sur le bouton Arrêter le compte à rebours le chronomètre sera arrêté et réinitialisé. (Si vous ne voyez pas d'effet cool lorsque le compte à rebours atteint zéro, réexécutez le stylet à l'aide du bouton en bas à droite de l'intégration.)
Voir le stylo SetTimeout Kittens de SitePoint ( @SitePoint ) sur CodePen .
Conclusion
 Une mise en garde potentielle à prendre en compte est le fait que  setTimeout  est asynchrone. Il met en file d'attente la référence de fonction qu'il reçoit pour s'exécuter une fois l'exécution de la pile d'appels en cours terminée. Cependant, il ne s’exécute pas simultanément ou sur un thread séparé (en raison de la nature à thread unique de JavaScript).
 console.log (1);
setTimeout (() => {console.log (2);}, 0);
console.log (3);
// Sorties: 1, 3, 2
 Bien que nous appelions  setTimeout  avec un délai de zéro seconde, les numéros sont toujours déconnectés. En effet, lorsque le minuteur de  setTimeout  a expiré, le moteur JavaScript place sa fonction de rappel dans une file d'attente,  derrière  les autres  consoles  console.log devant être
Si vous souhaitez en savoir plus sur ce qui se passe lorsque JavaScript s'exécute, je recommande vivement cette vidéo de JSConf 2014: Qu'est-ce que c'est que la boucle d'événements de toute façon?
requestAnimationFrame ()
Vous devez également être au courant de requestAnimationFrame . Cette méthode indique au navigateur que vous souhaitez appeler une fonction spécifiée avant le prochain repeint.
 Lors de la création d'animations, nous devons privilégier  requestAnimationFrame  plutôt que d'utiliser  setTimeout car cela se déclenchera grossièrement soixante fois par seconde, par opposition à  setTimeout qui est appelé après un minimum de  n  millisecondes. En utilisant  requestAnimationFrame nous pouvons éviter de modifier quelque chose deux fois entre deux mises à jour de trame.
 Voici un exemple d'utilisation de  requestAnimationFrame  pour animer un élément  div  à travers l'élément écran:
 const div = document.querySelector ('# rectangle');
laissez leftPos = 0;
function animateDiv () {
  leftPos + = 1;
  div.style.left = `$ {leftPos} px`;
  if (leftPos <100) requestAnimationFrame (animateDiv);
}
requestAnimationFrame (animateDiv);
 Vous pouvez, bien sûr, réaliser la même chose en utilisant  setTimeout :
 const div = document.querySelector ('# rectangle');
laissez leftPos = 0;
function animateDiv () {
  leftPos + = 1;
  div.style.left = `$ {leftPos} px`;
  if (leftPos <100) setTimeout (animateDiv, 1000/60);
}
animateDiv ();
 Mais comme mentionné, l'utilisation de  requestAnimationFrame  offre divers avantages, tels que permettre au navigateur d'effectuer des optimisations et d'arrêter des animations dans des onglets inactifs.
  Voir le stylo 
 Animation avec requestAnimationFrame  par SitePoint ( @SitePoint ) 
 sur  CodePen . 
jQuery.delay ()
 Enfin, je voudrais dissiper toute confusion entre l'utilisation du JavaScript natif  fonction setTimeout  et  méthode delay de jQuery .
 La méthode  delay  est spécialement conçue pour ajouter un délai entre les méthodes dans une file d'attente jQuery donnée. Il n'est pas possible d'annuler le retard. Par exemple, si vous souhaitez masquer une image pendant une seconde, la rendre visible pendant cinq secondes, puis la masquer pendant une seconde, vous pouvez procéder comme suit:
 $ ('img') .fadeIn (1000) .delay (5000) .fadeOut (1000);
  setTimeout  est mieux utilisé pour tout le reste.
  Remarque: si vous devez exécuter plusieurs fois le code après un délai spécifié, alors  setInterval  est plus adapté à la emploi. Vous pouvez lire  plus d'informations sur cette fonction ici . 
Conclusion
 Dans cet article, j'ai montré comment utiliser  setTimeout  pour retarder l'exécution d'une fonction. J'ai également montré comment passer des paramètres à  setTimeout conserver la  cette  valeur dans son rappel et aussi comment annuler un temporisateur.
 Si vous rencontrez un problème de codage concernant le l'utilisation de  setTimeout  (ou toute autre chose, vraiment), alors veuillez vous rendre sur les  forums SitePoint  où nous serons heureux de vous aider.
Source link
