Qu'est ce qu'une requête asynchrone ?
#1
Requête asynchrone qu'est-ce que ça veut dire ?
Lorsqu'un programme,quel qu'il soit, fait une requête il fait toujours une demande puis reçoit une réponse. Il s'écoule inévitablement un temps entre la demande et la réponse. 😎
Le programme a deux solutions pour gérer la situation :
- Il envoie la demande et se bloque en attendant la réponse. Dans ce cas la requête est dite synchrone.
- Il envoie la demande et continue son exécution. Il traitera la réponse quand elle arrivera. Dans ce cas la requête est dite asynchrone.
Etre capable de travailler avec des requêtes asynchrones n'est pas spécifique à JavaScript. Vous retrouver cette possibilité dans tout un tas de langages : C++, PHP, Python. En fait cette capacité ne dépend pas du langage mais plutôt de l'environnement. Si le système d'exploitation met à votre disposition une librairie d'entrées / sorties asynchrone alors vous le retrouvez au niveau d'un langage quel qu'il soit.
Il faut remarquer une chose qui est importante c'est qu'un programme monothread qui exécute une requête asynchrone n'est pas bloqué pendant l'exécution de la requête 🤩. Ca veut dire que ce programme va continuer son exécution et en particulier va continuer à être capable de traiter les événements clavier ou souris venant d'un éventuel opérateur. Par contre un programme monothread qui exécute une requête synchrone est bloqué pendant l'exécution de la requête 😴. Les événements clavier ou souris ne sont pas traités. Le navigateur est figé.

Par exemple sur un navigateur un script qui fait une requête AJAX depuis JavaScript. Cette requête est non bloquante. Le moteur JavaScript continue son exécution et l'internaute qui se trouve devant le navigateur n'est pas devant une application bloquée. Autre exemple en JavaScript sous Node.js, vous pouvez faire un appel système de manière asynchrone pour par exemple lire ou écrire dans un fichier. Ici c'est une librairie (libuv) qui fournit le service. Ca vous évite d'être obligé de coder une application multithread ou multiprocessus.
#2
Comment ça se passe au niveau de l'exécution du code ?
L'objectif c'est de faire une requête asynchrone puis une requête synchrone en utilisant l'objet JavaScript XMLHttpRequest
et de vous montrer ce qui se passe en cours d'exécution lorsque le navigateur est bloqué ou pas bloqué selon que la requête est asynchrone ou bien synchrone.
Pour cela j'ai besoin des trois fichiers que vous pouvez voir ci-dessous. Les trois fichiers sont sur mon serveur.
- Le premier fichier
req-asynchrone.html
est chargé dans le navigateur et fait une requêteasynchrone
vers le scriptprocess.php
qui lui reste sur le serveur et lui répond. - Le deuxième fichier
req-synchrone.html
fait une requête synchrone vers le même scriptprocess.php
. - Et
process.php
répond répond au deux requêtes en faisant unecho
deOK
mais après un délais de 20 secondes.

Le code du script process.php
est ci-dessous.
Le code du fichier req-asynchrone.html
qui va envoyer la requête asynchrone se trouve ci-dessous.
Ci-dessous vous pouvez constater que le console.log('Début')
de la ligne 8 s'exécute logiquement en premier puis attention c'est au tour du console.log('Fin')
de la ligne 24 puis on remonte à la ligne 17 pour exécuter le console.log('Traitement...')
lorsque la réponse est disponible c'est à dire 20 secondes après l'envoie de la requête.
Pendant que j'attends la réponse il est important de voir que je continue à avoir accès à la console. Je peux faire un console.log
de Bonjour
. De la même manière j'ai accès à la page web. S'il y avait des boutons je pourrais cliquer dessus. S'il y avait des formulaires je pourrais les remplir. En d'autres termes le navigateur continue de traiter les événements clavier et souris.

Ci-dessous je fais une petite modification du code pour demander une gestion synchrone de la requête. Je sauvegarde dans un nouveau fichier sous le nom de req-synchrone.html
. J'ajoute un booléen à false
au niveau de l'appel du xhr.open
c'est tout. C'est la seule différence avec le code précédent.
Ci-dessous vous pouvez constater de nouveau que le console.log('Début')
de la ligne 8 s'exécute logiquement en premier mais cette fois il faut attendre 20 secondes pour voir s'afficher le console.log('Traitement...')
de la ligne 13. Ici le code est bloqué sur le xhr.send
et pendant ce temps il est impossible d'exécuter quoi que ce soit à la console ni dans la page web. Le navigateur ou l'OS met les événements souris ou clavier en pile mais le moteur JavaScript ne les traite pas. Votre appli est figée. Ensuite c'est au tour du console.log('Fin')
de la ligne 19 de s'afficher. Au passage le navigateur nous affiche un warning pour nous rappeler que ce mode de fonctionnement est déprécié. Je l'utilise ici pour la démo mais ce n'est pas une bonne pratique de procéder ainsi.
Alors pourquoi ce changement de comportement ? Et bien parce qu'ici l'attente de la réponse est bloquante alors que précédemment elle était non bloquante. C'est la différence entre synchrone et asynchrone ! 😇
