Programmation Evenementielle !
Bonjour,
nous avons l'habitude d'utiliser les événements en leur associant via diverse méthode des handlers ou callbacks
mais rarement nous pensons à développer de façon événementielle.
généralement dans nos procédure nous avons des branchement (if switch) et des boucle (for foreach while) ainsi que des appels à des fonction ou méthodes.
Rarement nous nous posons de question sur ce découpage.
Dans la préhistoire de l'informatique, tout était fait ainsi. Du coup c'était le programme qui suivait son court et c'était à l'utilisateur de faire ce que le programme lui demandait.
Puis est apparue la programmation événementielle et les applications se sont mises à réagir aux actions de l'utilisateur.
À cette époque, les OS pour la plupart n'étaient pas multitâches. Du coup impossible de créer un thread comme on le fait en C ou Java. Lorsqu’une action est longue.
il filait trouver un moyen de rendre la main de temps en temps au reste du programme
Pour que l'utilisateur ait l'illusion que le traitement se faisait pendant qu'il continuait à travailler.
Quel rapport avec JavaScript me direz-vous ?
Simplement, que la gestion d'un script en JavaScript est monothread (HTML5 change un peu la donne)*! Nous nous retrouvons donc dans le même genre de situations que lorsque nos programmes étaient monotâche.
Pour régler ce problème la solution trouvée était très simple "rendre la main le plus souvent possible".
Du coup, on a pris l'habitude de gérer des événements. Et cela a changé notre façon de faire.
Un petit exemple j'ai un traitement que je veux déclencher lorsque l'utilisateur clique sur un bouton dans certaines conditions, via un menu, et sur un double click sur un élément d'un tableau.
Simple, direz-vous, je fais une fonction que j'appelle depuis chacun des événements cités.
Il y a pourtant une autre solution.
associer un événement «perso» à cette fonction
Chaque handler des boutons click menus n'ont alors plus qu'à émettre l'événement «perso» en question.
Cela ne change pas grand-chose sauf que le click sur le bouton à un gestionnaire de click qui gère des clicks et pas de traitement métier, on repasse par la gestion des événements donc s'il y a eu d'autres événements ils peuvent être traités avant, et si un changement d'affichage doit apparaitre le navigateur a pu faire le rendu.
par exemple sur le bouton la méthode onclick désactive le bouton et exécute une fonction longue
Lorsque l'utilisateur clique, la méthode désactive et change le style du bouton et exécute la fonction.
Pendant tout le temps d'exécution de la fonction, le bouton n'est pas désactivé. Lorsque la fonction se termine, le navigateur peut changer les propriétés du bouton et le désactiver.
Le même exemple avec un événement la méthode onclick désactive le bouton et lance l'événement "monaction" associer à cet événement une fonction longue.
lorsque l'utilisateur clique, la méthode désactive et change le style du bouton et lance l'événement "monaction"
Le navigateur reprend la main et désactive le bouton puis l'exécution de l'événement "onaction" arrive la fonction longue est exécutée.
De cette façon de faire a découlé une autre approche des traitements. Comme on vient de le voir, on peut assez facilement remplacer un appel de fonction par un événement.
Et cela peut avoir des conséquences étonnantes. Par exemple ne plus faire de boucle.
prenons un exemple
Soit un gros ensemble de données et un traitement à faire sur chaque élément.
La méthode classique consiste à parcourir la collection et traiter un à un chaque élément.
Maintenant si nous pensons événement voici ce que nous pouvons faire.
Nous associons à l'événement "traiter" une fonction qui prend en paramètre la collection et la position courante.
si la position est inférieure à la taille de la collection on traite l'élément correspondant à la position, on ajoute 1 à la position et si la position est inférieure à la taille on lance l'événement "traiter"
nous allons alors traiter tous les éléments, mais nous aurons la main pour traiter d'autres événements un click sur un bouton peut par exemple placer la position courante après la fin et interrompre ainsi le traitement un appel apax peut ajouter pendant le traitement de nouveaux éléments à la collection, etc.
Cette façon de faire rend les interfaces très fuies. Mais, on peut l'améliorer avec un événement à la fin de notre fonction plutôt que de lancer l'événement, on peut ajouter un timeout qui lui lancera l'événement.
le timeout n'est qu’un événement timer auquel on associe l'action de lancer l'événement "traiter"
de cette façon, on va pouvoir abaisser la priorité de traitement de la fonction (elle aura la main moins souvent)
Le piège est d'en mettre partout et d'empiler les événements sans jamais faire de traitement.
On parle beaucoup d'Asynchrone pour Ajax. En fait l'asynchronisme d'Ajax est basé sur les événements. Du coup on oublie que nous pouvons nous aussi utiliser les événements dans le traitement de la réponse.
De cette époque totalement monotâche nous avons su tirer le meilleur de la programmation événementielle pour nos applications fluides. la solution était simple
elle reposait sur une question
Dois-je appeler directement la méthode ou passer par un événement ?
et la réponse était simple
Si avant cet appel l'IHM a été modifié alors il faut passer par un événement.
Si le traitement est long alors, passez par un événement.
JavaScript permet de gérer son IHM de la sorte.
si comme moi vous êtes un adepte de MVC, pensez que vous pouvez ajouter des événements et des gestionnaires à vos contrôles à vos pools de données, etc.
A+JYT