Jai passé des rappels ou simplement déclenché les fonctions dune autre fonction de mes programmes pour que les choses se passent une fois les tâches terminées. Quand quelque chose se termine, je déclenche directement la fonction:

 var ground = "clean"; function shovelSnow(){ console.log("Cleaning Snow"); ground = "clean"; } function makeItSnow(){ console.log("It"s snowing"); ground = "snowy"; shovelSnow(); }  

Mais je « ve lire sur de nombreuses stratégies différentes en programmation, et une que je comprends être puissante, mais que je nai pas encore pratiquée, est basée sur les événements (je pense quune méthode que jai lue sappelait « pub-sub » ) :

 var ground = "clean"; function shovelSnow(){ console.log("Cleaning Snow"); ground = "clean"; } function makeItSnow(){ console.log("It"s snowing"); ground = "snowy"; $(document).trigger("snow"); } $(document).bind("snow", shovelSnow);  

Jaimerais comprendre les forces et faiblesses objectives de lévénement la programmation basée sur le fait dappeler simplement toutes vos fonctions à partir dautres fonctions. Dans quelles situations de programmation la programmation basée sur les événements est-elle judicieuse?

Commentaires

  • En passant, vous pouvez simplement utiliser $(document).bind('snow', shovelShow). Inutile de lenvelopper dans une fonction anonyme.
  • Vous voudrez peut-être également en savoir plus sur la  » programmation réactive « , qui a beaucoup en commun avec la programmation événementielle.

Réponse

Un événement est une notification décrivant une occurrence du passé récent.

Une implémentation typique dun système événementiel utilise un répartiteur dévénements et des fonctions de gestion (ou abonnés ). Le répartiteur fournit une API pour relier les gestionnaires aux événements (jQuery « s bind), et une méthode pour publier un événement à ses abonnés (trigger dans jQuery). Lorsque vous parlez dévénements IO ou UI, il existe également généralement une boucle dévénement , qui détecte les nouveaux événements tels que les clics de souris et les transmet au répartiteur. JS-land, le répartiteur et la boucle dévénements sont fournis par le navigateur.

Pour le code qui interagit directement avec lutilisateur – répondant aux pressions et aux clics – programmation événementielle (ou une variante de celle-ci, telle que programmation réactive fonctionnelle ) est presque inévitable. Vous, le programmeur, n’avez aucune idée du moment et de l’endroit où l’utilisateur cliquera, alors tout dépend du cadre graphique. ou navigateur pour détecter laction de lutilisateur dans sa boucle dévénements et notifier votre code. Ce type dinfrastructure est également utilisé dans les applications réseau (cf NodeJS).

Votre exemple, dans lequel vous déclenchez un événement en yo votre code plutôt que dappeler directement une fonction a des compromis plus intéressants, dont je parlerai ci-dessous. La principale différence est que léditeur dun événement (makeItSnow) ne spécifie pas le destinataire de lappel; qui « est câblé ailleurs (dans lappel à bind dans votre exemple). Cela sappelle feu-et-oubliez : makeItSnow annonce au monde quil neige, mais il ne se soucie pas de qui écoute, de ce qui se passe ensuite ou du moment où cela se produit – il diffuse simplement le message et se dépoussière.


Ainsi, lapproche événementielle dissocie lexpéditeur du message du récepteur. Un avantage que cela vous offre est quun événement donné peut avoir plusieurs gestionnaires. Vous pouvez lier une fonction gritRoads à votre événement de neige sans affecter le gestionnaire shovelSnow existant. Vous disposez dune flexibilité dans la manière dont votre application est câblée; pour désactiver un comportement, il vous suffit de supprimer lappel bind plutôt que de parcourir le code pour trouver toutes les instances du comportement.

Un autre avantage de la programmation événementielle est quelle vous donne un endroit pour mettre des préoccupations transversales. Le répartiteur dévénements joue le rôle de Médiateur , et certaines bibliothèques (telles que Plus clair ) utilisent un pipeline afin que vous puissiez facilement intégrer des exigences génériques telles que la journalisation ou la qualité de service.

Divulgation complète: Brighter est développé chez Huddle, où je travaille.

Un troisième avantage du découplage de lexpéditeur dun événement du récepteur est quil vous donne de la flexibilité dans quand vous gérez lévénement. Vous pouvez traiter chaque type dévénement sur son propre thread (si votre répartiteur dévénements le prend en charge), ou vous pouvez placer des événements déclenchés sur un courtier de messages tel que RabbitMQ et les gérer avec un processus asynchrone ou même les traiter en masse pendant la nuit. Le récepteur de lévénement peut être dans un processus séparé ou sur une machine distincte. Il nest pas nécessaire de changer le code qui déclenche lévénement pour cela! Cest la grande idée derrière les architectures « microservices »: les services autonomes communiquent à laide dévénements, avec un middleware de messagerie comme épine dorsale de lapplication.

Pour un exemple assez différent de style événementiel, regardez la conception axée sur le domaine, où événements de domaine sont utilisés pour aider à séparer les agrégats. Par exemple, considérez une boutique en ligne qui recommande des produits en fonction de votre historique dachat. Un Customer doit avoir son historique dachat mis à jour lorsquun ShoppingCart est payé. Lagrégat ShoppingCart peut notifier le Customer en déclenchant un événement CheckoutCompleted; le Customer serait mis à jour dans une transaction séparée en réponse à lévénement.


Le principal inconvénient de ce modèle événementiel est lindirection. Il est maintenant plus difficile de trouver le code qui gère lévénement car vous ne pouvez pas simplement y accéder en utilisant votre IDE; vous devez trouver où l événement est lié dans la configuration et espérer que vous avez trouvé tous les gestionnaires. Il ya plus de choses à garder dans votre tête à tout moment. Les conventions de style de code peuvent être utiles ici (par exemple, mettre tous les appels à bind dans un seul fichier). Pour votre santé mentale, il est important de nutiliser quun seul répartiteur d événements et de l utiliser de manière cohérente.

Un autre inconvénient est quil est difficile de refactoriser les événements. Si vous avez besoin de changer le format dun événement, vous devez également changer tous les récepteurs. Ceci est exacerbé lorsque les abonnés dun événement sont sur des machines différentes, car maintenant vous devez synchroniser les versions du logiciel!

Dans certaines circonstances, les performances peuvent être un problème. Lors du traitement dun message, le répartiteur doit:

  1. Rechercher les bons gestionnaires dans une structure de données.
  2. Construire un pipeline de traitement des messages pour chaque gestionnaire. Cela peut impliquer un tas dallocations de mémoire.
  3. Appelez dynamiquement les gestionnaires (éventuellement en utilisant la réflexion si le langage lexige).

Cest certainement plus lent quune fonction ordinaire call, qui consiste uniquement à pousser une nouvelle image sur la pile. Cependant, la flexibilité quune architecture événementielle vous offre facilite considérablement lisolement et loptimisation du code lent. Avoir la possibilité de soumettre du travail à un processeur asynchrone est une grande victoire ici, car cela vous permet de répondre immédiatement à une demande tandis que le travail acharné est traité en arrière-plan. Dans tous les cas, si vous interagissez avec la base de données ou dessinez des éléments à lécran, les coûts dE / S submergeront totalement les coûts de traitement dun message. Il sagit déviter une optimisation prématurée.


En résumé, les événements sont un excellent moyen de créer des logiciels faiblement couplés, mais ils ne sont pas sans coût. Ce serait une erreur, par exemple, de remplacer chaque appel de fonction dans votre application par un événement. Utilisez des événements pour créer des divisions architecturales significatives.

Commentaires

  • Cette réponse dit la même chose que 5377 ‘ réponse de s que jai choisie comme correcte; Je ‘ modifie ma sélection pour marquer celle-ci car elle élabore davantage.
  • La vitesse est-elle un inconvénient majeur du code événementiel? Cela semble possible, mais je ne ‘ pas tout à fait savoir.
  • @ raptortech97 cela peut certainement lêtre. Pour le code qui doit être particulièrement rapide, vous voudrez probablement éviter denvoyer des événements dans une boucle interne; heureusement, dans de telles situations, ce que vous devez faire est généralement bien défini, vous navez donc ‘ pas besoin de la flexibilité supplémentaire des événements (ou publier / souscrire ou observateurs, qui sont des mécanismes équivalents avec terminologie différente).
  • Notez également quil existe des langages (par exemple Erlang) construits autour du modèle dacteur où tout est des messages (événements). Dans ce cas, le compilateur peut décider dimplémenter les messages / événements sous forme dappels de fonction directs ou de communication.
  • Pour les performances  »  » Je pense que nous devons faire la distinction entre les performances mono-thread et lévolutivité. Les messages / événements peuvent être pires pour les performances monothread (mais peuvent être convertis en appels de fonction pour un coût supplémentaire nul et pas pire), et pour lévolutivité, il ‘ est supérieur dans pratiquement tous les (par exemple, susceptible d’améliorer considérablement les performances des systèmes multi-processeurs modernes et futurs  » many-CPU « ).

Réponse

La programmation basée sur les événements est utilisée lorsque le programme ne contrôle pas la séquence dévénements quil exécute. Au lieu de cela, le flux du programme est dirigé par un processus extérieur tel quun utilisateur (par exemple, une interface graphique), un autre système (par exemple un client / serveur) ou un autre processus (par exemple RPC).

Par exemple, un script de traitement par lots sait ce quil doit faire pour quil le fasse. Il nest pas basé sur des événements.

Un traitement de texte se trouve là et attend que lutilisateur commence à taper.Les pressions sur les touches sont des événements qui déclenchent la fonctionnalité de mise à jour du tampon de document interne. Le programme ne peut pas savoir ce que vous voulez taper, il doit donc être piloté par les événements.

La plupart des programmes GUI sont pilotés par les événements car ils sont construits autour de linteraction de lutilisateur. Cependant, les programmes basés sur des événements ne se limitent pas aux interfaces graphiques, cest simplement lexemple le plus familier à la plupart des gens. Les serveurs Web attendent que les clients se connectent et suivent un idiome similaire. Les processus darrière-plan sur votre ordinateur peuvent également répondre aux événements. Par exemple, un antivirus à la demande peut recevoir un événement du système dexploitation concernant un fichier nouvellement créé ou mis à jour, puis analyser ce fichier à la recherche de virus.

Réponse

Dans une application basée sur des événements, le concept des écouteurs dévénements vous donnera la possibilité décrire encore plus Applications faiblement couplées .

Par exemple, un module ou un plug-in tiers peut supprimer un enregistrement de la base de données, puis déclencher le receordDeleted et laissez le reste aux écouteurs dévénements pour quils fassent leur travail. Tout fonctionnera correctement, même si le module de déclenchement ne sait même pas qui écoute cet événement particulier ou ce qui devrait se passer ensuite.

Réponse

Une analogie simple que je voulais ajouter et qui ma aidé:

Pensez aux composants (ou objets) de votre application comme à un grand groupe damis Facebook.

Lorsquun de vos amis veut vous dire quelque chose, il peut soit vous appeler directement, soit le publier sur son mur Facebook. Lorsquils le publient sur Facebook, nimporte qui pourrait le voir et y réagir, mais beaucoup de gens ne le font pas. Parfois, cest quelque chose dimportant que les gens auront probablement besoin de réagir, comme « Nous allons avoir un bébé! » ou « Un groupe de so-and-so fait un concert surprise au Drunkin « Barre de palourdes! ». Dans le dernier cas, le reste des amis devra probablement réagir, surtout s’ils sont intéressés par ce groupe.

Si votre ami veut garder un secret entre vous et eux, il est probable qu’il ne le publieraient pas sur leur mur Facebook, ils vous appelleraient directement et vous le diraient. Imaginez un scénario où vous dites à une fille que vous aimez que vous aimeriez la rencontrer dans un restaurant pour un rendez-vous. Au lieu de l’appeler directement et de lui demander elle, vous la publiez sur votre mur Facebook pour que tous vos amis puissent la voir. Cela fonctionne, mais si vous avez un ex jaloux, elle pourrait le voir et apparaître au restaurant pour gâcher votre journée.

Quand pour décider sil faut intégrer ou non des écouteurs dévénements pour mettre en œuvre quelque chose, pensez à cette analogie. Ce composant doit-il faire connaître son activité à tout le monde? Ou doit-il appeler quelquun directement? Les choses peuvent se compliquer assez facilement, alors soyez attention.

Réponse

Cette analogie suivante pourrait vous aider u pour comprendre la programmation dE / S pilotée par événement en dessinant un parallèle avec la file dattente à la réception du docteur.

Bloquer les E / S, cest comme, si vous êtes dans la file dattente, la réceptionniste demande à un gars en face de vous de remplir le formulaire et elle attend quil ait fini. Vous devez attendre votre tour jusquà ce que le gars termine son formulaire, cest bloquant.

Si un célibataire prend 3 minutes à remplir, le 10ème doit attendre 30 minutes. Maintenant, pour réduire ce 10e temps d’attente, la solution serait d’augmenter le nombre de réceptionnistes, ce qui est coûteux. Cest ce qui se passe dans les serveurs Web traditionnels. Si vous demandez des informations sur l’utilisateur, les autres utilisateurs devraient attendre la lopération en cours, lextraction de la base de données, est terminée. Cela augmente le « temps de réponse » de la 10e demande et augmente de façon exponentielle pour le nième utilisateur. Pour éviter cela, les serveurs Web traditionnels créent un thread (équivalent à un nombre croissant de réceptionnistes) pour chaque demande. , cest-à-dire, en gros, il crée une copie du serveur pour chaque requête, ce qui est coûteux en termes de consommation de processeur, car chaque requête nécessitera un thread de système dexploitation. Pour faire évoluer lapplication, vous devrez fournir beaucoup de puissance de calcul à lapplication .

Event Driven : Lautre approche pour augmenter le temps de réponse de la file dattente est de optez pour une approche événementielle, où les gars dans la file dattente se verront remettre le formulaire, demandé à remplir et à revenir une fois terminé. Par conséquent, la réceptionniste peut toujours prendre la demande. Cest exactement ce que javascript a fait depuis sa création. Dans le navigateur, javascript répondrait à lévénement de clic de lutilisateur, au défilement, au balayage ou à la recherche de base de données, etc. objets et ils peuvent être passés en tant que paramètres à dautres fonctions (appelées rappels), et peuvent être appelés à la fin dune tâche particulière. Cest exactement ce que fait node.js sur le serveur.Vous pouvez trouver plus dinformations sur la programmation événementielle et le blocage des E / S, dans le contexte du nœud ici

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *