Modèles de programmation réactive mentale pour les superviseurs


Cet article est destiné à un large éventail de lecteurs qui souhaitent savoir ce qu'est la programmation réactive. Le but de cet article est de former vos modèles mentaux de base de programmation réactive (MM RP) sans entrer dans les détails techniques.

Avertissement
( ) — , . , .
, : , . , , .
.

Mais d'abord, expliquons ce que les modèles mentaux et supérieurs mentionnés dans le titre de l'article ont à voir avec cela ...

À propos des modèles mentaux
, , , . , .
, , (. [1], [2])
? , , . (), , , . , , «», «» « » .
, , (), , - ().

Et voici les patrons ...
. «» «» , : . ( , «» , ).
, «» , , , , , . , . «» «». , , , .
, , , .., () — , , .
, .


Pourquoi la programmation réactive a-t-elle besoin de votre projet?


Beaucoup de gens qui ne connaissent pas RP sont initialement sceptiques à son égard, soupçonnant que ce n'est qu'une autre mode vide, couverte de quelques beaux mots. Surtout quand ils apprennent que vous ne pouvez évaluer la RP qu'en l'essayant. Et l'essayer coûte cher, en raison du seuil d'entrée élevé. Nous avons vécu et vécu avec OOP, qu'est-ce qui lui manque?
Permettez-moi de présenter mon point de vue à ce sujet.
À l'aube de la programmation, lorsque la plupart des programmes étaient écrits directement en langage assembleur, le concept de travail principal (un élément du modèle mental) des programmeurs était une instruction ou une commande de langage. Certaines données (primitives) sont transmises à l'entrée d'une commande ou d'une instruction. L'instruction traite et émet certaines données de sortie. L'apparition des premiers langages de programmation procédurale tels que Fortran n'a pas changé l'essence de la question. Seules les données et les opérations effectuées (comme une séquence de commandes élémentaires) sont devenues plus compliquées.
Au fil du temps, il est devenu clair que ce concept n'était pas très cohérent avec les réalités du monde. Il peut y avoir beaucoup de données, elles peuvent être difficiles à structurer. Les données et les fonctionnalités qui les entourent seraient intéressantes à diviser en parties, à développer et à maintenir séparément, et à utiliser ensemble.
La POO a résolu ces problèmes de plusieurs façons. L'unité du modèle mental d'un programmeur OOP typique est un objet avec des données cachées (encapsulées) et une interface d'accès à ces données comme un ensemble de fonctions.
La POO a joué un rôle énorme dans l'automatisation et l'informatisation de nombreux processus de fabrication et autres. Et avec cela, ses faiblesses ont été exposées.
Malheureusement, dans la POO, il n'y a pas de concept de processus en tant que tel.
Ils ont essayé d'améliorer la situation de différentes manières, en se concentrant sur divers aspects.
Ainsi, la programmation événementielle [3], la programmation de flux de données [4], le traitement de flux [5] et plusieurs autres paradigmes sont nés.
Je me risquerais à susciter un flot de critiques envers les adeptes et les experts de ces paradigmes, en essayant de transmettre en termes simples leur essence générale.
D'une manière ou d'une autre, ces paradigmes fonctionnent avec des flux d'informations. Dans le même temps, la programmation événementielle, comme son nom l'indique, se concentre sur le processus d'émergence d'éléments de flux d'informations, la programmation de flux de données - sur le contrôle de flux (fractionnement, fusion, transformation de flux) et le traitement de flux sur l'utilisation optimale des ressources dans le traitement des flux.
La programmation réactive est à peu près la même chose, mais avec un accent sur les opérations élémentaires spécifiques de création, de gestion et d'utilisation des threads. Ceux. RP décrit comment votre système réagit (l'anglais réagit) aux éléments du flux d'informations. Dans ce sens, il serait plus correct en russe d'utiliser le terme «programmation de réactifs» (du mot «réagir») ou «programmation de réaction» (du mot «réaction à quelque chose») s'il ne s'agissait pas de couper l'oreille, et le second n'a pas causé d'associations incorrectes.
J'oserais exprimer une autre pensée séditieuse. Ce que nous appelons aujourd'hui la programmation réactive en anglais (programmation réactive). appelé ainsi pour des raisons historiques et incliné en faveur de ce terme l'opinion majoritaire.
Ce paradigme aurait pu être appelé différemment. Par conséquent, ne vous concentrez pas sur son nom actuel, mais essayez de comprendre son essence.
Et bien que je parlerai de RP à un niveau assez abstrait, je citerai les API de la bibliothèque RxJS comme exemples concrets.
L'acronyme RxJS signifie Reactive Extension for JavaScript, une extension JavaScript pour les fonctionnalités de programmation réactive. Des extensions similaires existent pour de nombreux autres langages de programmation, comme on peut le voir dans l'image ci-dessous, tirée de [6].
Extensions de programmation réactives

Pourquoi les modèles mentaux de RP ont-ils besoin de votre projet


Les grands projets ne se font pas seuls. Vous pouvez souvent lire ou entendre que les participants au projet doivent parler la même langue. Mon expérience montre que ce n'est guère nécessaire et possible. Mais ce qu'il faut, c'est que les concepts les plus élémentaires du projet soient énoncés et compris par les participants au projet aussi équitablement que possible. En termes de modèles mentaux (MM), nous pouvons dire que les MM de niveau supérieur devraient être aussi similaires que possible.
Mais comment peuvent-ils être similaires si les analystes pensent en termes de workflow et de cas d'utilisation, les architectes dans les modèles, les développeurs dans les fonctions et les structures de données et les testeurs dans les scénarios de test?
Je n'invite pas tous ces spécialistes à commencer à penser en même temps aux catégories de programmation réactive, mais je peux leur promettre que la connaissance de ces catégories simplifiera et augmentera l'efficacité de leur communication professionnelle avec leurs collègues. Cela devrait se produire car, d'une part, les MM RP ont la puissance nécessaire pour décrire des workflows complexes, et d'autre part, les MM RP peuvent être directement convertis en code dans de nombreux langages de programmation.

Surprises, dangers, ou qu'en RP ce n'est pas la façon dont nous sommes tous habitués


Mais avant d'entrer dans la description de la composition des modèles mentaux de programmation réactive, sur la base de notre propre expérience, je voudrais avertir le lecteur de ce qui n'y est pas. De plus, non seulement non, mais l'attente même d'un comportement de POO simple et compréhensible dans le monde entraîne de tristes conséquences.
Je fais cela non pas pour intimider, mais plutôt pour intriguer le lecteur.

Différence 1: au lieu d'un modèle de curseur, un graphique de calcul


Je vais oser suggérer que de nombreux lecteurs, lorsqu'ils réfléchissent à la prochaine tâche à réaliser, ont un modèle mental dans leur tête, que j'appelle le modèle du curseur. Il suppose qu'un algorithme étape par étape sous la forme d'une liste linéaire d'instructions sera inventé pour résoudre le problème. L'exécution de l'algorithme se réduit à l'exécution pas à pas des instructions les unes après les autres. Vous pouvez imaginer quelque chose comme un pointeur sur l'instruction en cours d'exécution. Une fois l'instruction exécutée, le pointeur (curseur) passe à l'instruction suivante de la liste et commence à s'exécuter.
Dans ce modèle, une séquence de commandes écrites dans un langage de programmation orienté objet conditionnel
1. 1 = 2
2. 2 = 3 
3. 3 = 1 + 2
4.  1, 2, 3
5. 1 = 4
6.  1, 2, 3

donnera le résultat
2 3 5
4 3 5

Notre modèle mental de curseur prédit et explique parfaitement un tel résultat. Après avoir traité la troisième ligne, la valeur X3 est définie et la nouvelle valeur pour X1 spécifiée à la ligne 5 ne peut pas la modifier.
Dans le monde de RP, selon l'interprétation de l'opération «+», le résultat sera très probablement
2 3 5
4 3 7

Dans ce monde, la plupart des opérations connectent les paramètres d'entrée les uns aux autres, créant ainsi des graphiques de calcul à travers lesquels les calculs sont «poussés» lorsqu'un ou plusieurs paramètres sont modifiés.

Différence 2: opérations asynchrones


Dans le cadre du modèle mental de calcul du curseur, l'opération suivante ne peut pas commencer plus tôt que la précédente.
Prenons l'exemple suivant. Supposons que la fonction f1 calcule le salaire de base par la valeur de l'identifiant utilisateur userId et que la fonction f2 calcule le bonus en fonction de userId et la valeur du salaire.
Ensuite, le calcul du salaire complet peut ressembler à ceci
1. X = f1(userId)
2. Y = f2(userId, X)
 X, Y

Supposons qu'un membre du personnel ait un salaire de base de 10 000. et un bonus de 1000 unités.
Notre modèle mental de curseur vous indique quoi imprimer.
10000 1000 

Hélas, dans le monde des RP asynchrones, le résultat peut, selon la durée des opérations, être
0 0 
10000 0 
0 1000 
10000 1000 

(Je ne considère pas encore les exceptions).
Le fait est que dans le monde asynchrone-réactif, l'opération suivante n'attend pas la fin de la précédente, si c'est la précédente) asynchrone.
Pour illustrer cela, regardons quelques détails importants en utilisant l'exemple réaliste montré dans la figure ci-dessous.
L'image montre le temps d'exécution de quatre instructions L1, L2, L3 et L4 qui sont indépendantes les unes des autres (leur nombre est important pour nous, pas l'orthographe) en modes synchrone (partie supérieure de l'image) et asynchrone (partie inférieure de l'image).

Comme on le voit, dans le premier cas, chaque instruction suivante "attend" la fin de la précédente. Dans le cas asynchrone, toutes les instructions commencent à être exécutées simultanément. En raison de l'exécution parallèle et de l'utilisation des ressources, la plupart des instructions s'exécutent en mode asynchrone plus longtemps qu'en mode synchrone. Cependant, ensemble, ils légueront leur travail plus tôt.
L'ordre d'achèvement des instructions dans les deux modes est également très différent. En synchronisme, il:
L1, L2, L3, l4
mais en asynchrone:
L3, L2, L1, L4
.

Différence 3: les chaînes incomplètes (sans consommateur) ne fonctionnent pas du tout


Dans de nombreux langages de programmation traditionnels, il est courant d'associer des appels de fonction ou des propriétés d'objet à des points.
Par exemple, la chaîne d'appel de fonction JavaScript suivante transforme le mot «bon» en «chien»:
„good“.split(„“).reverse().join(„“).replace(„oo“, „o“);

Les séquences (chaînes) peuvent être longues. Pour des raisons de réutilisation ou de commodité, ils peuvent être découpés en morceaux et partiellement réalisés.
La division d'une chaîne en RP en deux parties et l'appel d'une seule d'entre elles conduisent généralement à un manque de résultat, car seule la chaîne complète (avec le consommateur à la fin) est effectuée.

Pourquoi tout ça?


Probablement, de nombreux lecteurs se posent déjà la question: «Ne sont-ils pas devenus fous collectivement, ces programmeurs réactifs? Pourquoi est-il nécessaire, une telle programmation? "
Je ne prétends pas prédire ce que les créateurs et les experts de la République de Pologne répondraient à cette question, mais ma réponse est la suivante: une telle programmation est nécessaire, car de nombreux objets du monde réel se comportent exactement comme ça.
Graphiques informatiques - c'est ce sur quoi Excel est construit, à partir duquel les comptables, mais aussi les chefs de projet sont ravis.
Opérations asynchrones . Lorsque vous faites du café ou du thé dans votre cuisine, vous tenez-vous tout le temps dans la cuisine et regardez votre cafetière ou votre théière? Non. L'appareil fait bouillir de l'eau et fait son travail pendant que vous faites autre chose pour l'instant.
Chaîne d'opérations complète.Essayez de débrancher votre lampe de bureau de la prise murale et d'appuyer sur l'interrupteur. La lampe ne s'allume pas de cela. Cet objet ne fonctionne que s'il existe une chaîne complète - de la source au consommateur d'électricité. Et il y a beaucoup, sinon la plupart, de tels objets dans le monde réel.

Je veux vous rassurer, votre connaissance de la programmation traditionnelle et du curseur MM ne doit pas être jetée à la poubelle à cause de l'apparition de RP. La programmation réactive les a laissés seuls et les a étendus avec de nouvelles opérations sur de nouveaux types d'objets. Comment - nous en parlerons plus tard.

L'espace de la programmation des modèles mentaux et la place de MM RP


Parlant de la place du RP dans le paysage général de la programmation, les auteurs mentionnent souvent deux dimensions - la complexité des objets traités et le synchronisme / asynchronie des opérations. Un exemple d'une telle classification peut être trouvé dans le livre «RxJS en action» [7], dans le chapitre «Quand et où utiliser RxJS».
Dans cette classification, la dimension des objets est divisée en objets uniques et multi-objets: tableaux, listes, etc. Les opérations sont divisées en synchrones et asynchrones.
Ainsi, cette classification divise le monde de la programmation en quatre domaines. RP est l'un de ces domaines responsable du traitement multi-objets avec des opérations asynchrones.
Je trouve cette classification très intéressante, mais je voudrais la regarder du point de vue des modèles mentaux. Le tableau ci-dessous les présente.
Valeurs et objets uniques, ,
, (Stream)
, (Promise)(Workflow)

Nous supposons que les modèles mentaux d'instructions et le curseur ne nécessitent pas d'explication supplémentaire.
Le cycle est une extension des instructions MM et le curseur en raison des instructions supplémentaires du cycle ou revenir à un certain point. Cela permet à un ensemble d'instructions de traitement pour un seul objet de «boucler» dans une boucle, et ainsi de traiter de nombreux objets de ce type. Dans ce cas, le curseur se déplace à l'intérieur du cycle comme dans le modèle précédent, et ayant atteint le point de transition, il saute au début ou le traitement du cycle s'arrête si tous les objets sont traités.
Jet. La différence entre ce modèle mental et le précédent est que le curseur
pointant vers l'objet en cours de traitement reste en place et que les objets eux-mêmes le «survolent».
Regardons cela avec deux exemples. Si vous peignez une clôture en bois, vous, par analogie avec le modèle de curseur, passez de planche en planche. Mais l'ouvrier sur le convoyeur reste en place et, par analogie avec le modèle de jet, les pièces à traiter elles-mêmes s'en approchent. De tels objets sont souvent désignés par le terme English Stream, par exemple, dans le langage Java.
Sémaphore. Ce MM est plus facile à associer à un feu de circulation à une intersection. Les objets asynchrones interrogent périodiquement l'état d'une variable publique et effectuent certaines actions après avoir changé son état. (comme des conducteurs devant un feu de circulation)
En attente.Une métaphore appropriée pour ce modèle d'attentes mentales est la lettre sur papier ou Emall que vous attendiez la dernière fois que vous avez obtenu votre emploi. Il peut y avoir une réponse positive ou négative. Votre comportement après avoir reçu la lettre dépend beaucoup de son contenu. Le terme anglais Promise est souvent utilisé pour décrire ces types d'objets. Que, du point de vue de l'utilisateur, c'est une attente, pour l'entrepreneur qui fournit les services, c'est plutôt une promesse.
Comme nous le voyons dans la description, le mouvement le long de chaque dimension (de haut en bas ou de droite à gauche dans le tableau) signifie un changement qualitatif dans le modèle mental.
Comme le montre le tableau, les jets et les attentes sont voisins à gauche et en haut de la cellule sud-est qui nous intéresse. Qu'y a-t-il de nouveau dans les modèles mentaux de flux qui habitent la cellule qui nous intéresse par rapport à eux?

Quelle est l'extension?


L'expansion de Streams par rapport aux attentes est que les informations attendues peuvent arriver non pas une fois, mais en plusieurs parties. Dans ce cas, le processus peut se terminer sans se terminer. Ceux. après une série de portions réussies, nous recevrons une notification d'erreur. De plus, une autre version des informations est ajoutée - une notification de la fin du processus.
Cela signifie, par exemple, qu'il est possible de recevoir plusieurs (mais pas toutes) parties des informations attendues et (sans message d'erreur) un message concernant la fin du traitement.
Rappelons à nouveau, avec Waiting, nous n'avons que deux options alternatives pour les informations résultantes.
Le modèle Mental Jet est bien adapté pour comprendre, discuter et mettre en œuvre le processus de transformation d'une séquence d'objets du même type. MM Stream le développe avec les aspects suivants:
  • Il peut y avoir de nombreux jets et nous pouvons les fusionner ensemble
  • Les jets peuvent être hétérogènes
  • Nous pouvons diviser les jets en nouveaux selon différents critères
  • Nous pouvons les «fermer» et / ou les transformer en nouveaux dans le cadre d'un même flux.

Nous avons donc déterminé la place de MM RP (Streams) dans l'espace ou le paysage des objets de Programmation. Abaissons maintenant la vue à vol d'oiseau et examinons de plus près les flux et leurs modèles mentaux.

Flux et phases de leur cycle de vie


En première approximation, les flux de RP peuvent être imaginés comme des flux d'eau dans des conduites d'eau ou des flux d'électricité. Il convient de rappeler que, comme toute autre analogie, cette analogie a ses limites et n'est pas toujours applicable.
En parlant de flux, on peut distinguer les aspects importants suivants:

  1. Chaque fil se pose en quelque sorte
  2. Il se dirige en quelque sorte vers le consommateur.
  3. Il se passe quelque chose avec lui (il se transforme)
  4. Il peut être divisé en plusieurs flux ou fusionné avec d'autres flux
  5. Le consommateur utilise en quelque sorte le flux, cessant d'exister.

Les aspects énumérés sont simultanément des phases du cycle de vie des éléments individuels du flux.
Examinons-les plus en détail en utilisant l'exemple des fonctions RxJS.

Création de threads


Les flux peuvent être créés à partir d'éléments passifs tels qu'un tableau ou une liste d'objets dans votre programme, octets, lignes de fichiers, etc. Ce type de sources de flux est appelé froid (bien qu'il existe techniquement une définition plus précise des sources de flux froid).
Les soi-disant sources chaudes "vivent leur propre vie" et si vous ne vous connectez pas à temps, les informations seront perdues. Cette catégorie comprend des informations sur les actions de l'utilisateur sur un ordinateur, une tablette, un smartphone, par exemple, des informations sur les frappes, les mouvements de la souris ou le toucher de l'écran. Cette catégorie comprend également les données demandées par divers protocoles tels que HTTP, les données de divers capteurs.
Il convient de noter qu'il existe des sources dites «chaudes». De plus, certaines sources «chaudes» peuvent être «refroidies» et «froides» peuvent être «réchauffées». Mais vous devriez lire à ce sujet dans la littérature spéciale, par exemple, dans le livre [7].
Il est important pour nous de savoir que toutes les opérations de création de flux créent des objets du même type, qui peuvent être traités ultérieurement par les mêmes opérations, quel que soit leur contenu. Dans cet article, nous appelons ces flux d'objets. Le nom anglais correspondant est Observable.

Mouvement des consommateurs et transformation des flux


Les opérations de transformation des flux peuvent être effectuées aussi bien sur le chemin du consommateur que par lui-même. Dans les deux cas, les traitements des éléments de flux sont strictement séquentiels, c'est-à-dire l'opération suivante n'est lancée que lorsque la précédente est terminée et lui a transmis son résultat.
Contrairement à Stream, qui dans certains langages de programmation sont des constructions de langage avec leur propre syntaxe et sémantique, les extensions réactives comme RxJS en JavaScript sont obligées d'utiliser la syntaxe et la sémantique de base du langage extensible. Par conséquent, RxJs implémente la fonction pipe (), à l'intérieur de laquelle vous pouvez placer des appels aux fonctions - gestionnaires du flux lui-même et de ses éléments individuels.
Il est important de noter que seules les fonctions spéciales pouvant être canalisées peuvent être des gestionnaires de flux.

"Débit triphasé"


Si nous continuons l'analogie avec l'électricité, alors les flux que nous considérons peuvent être appelés triphasés. Outre le «fil normal» transmettant les informations de base, il existe également un «fil d'erreur» et un «fil de terminaison de flux». Les opérations de transformation permettent non seulement de changer l'objet, mais aussi de le rediriger vers un autre «fil». Cette technique est utilisée, par exemple, lors du traitement d'erreurs présumées lors de l'utilisation de serveurs utilisant le protocole HTTP. Par exemple, si un serveur ne répond pas, vous pouvez essayer d'en demander un autre sans informer l'utilisateur de l'échec de la demande du premier serveur.
Ceci est un autre élément très important de votre modèle de flux mental. Si, dans les paradigmes de programmation traditionnels, l'erreur est renvoyée par la fonction de traitement sous forme de code d'erreur ou doit être interceptée en tant qu'interruption (exception), alors dans les flux l'erreur "circule" indépendamment du canal principal.
Là, il peut être traité. Par exemple, si un utilisateur a entré un mot de passe incorrect, il peut avoir la possibilité supplémentaire de tenter de le saisir une ou plusieurs fois.

Fractionnement et fusion de flux


La répartition des flux s'effectue en deux étapes. À la première étape, les threads vides sont démarrés. Ensuite, dans la deuxième étape (étape de traitement de flux), dans l'une des fonctions de traitement, les éléments seront analysés et redirigés vers le flux souhaité. Techniquement, il existe de nombreuses options pour ce faire. Par exemple, le supprimer du thread actuel ou le cloner avant de le démarrer dans un nouveau thread.
Vous pouvez fusionner plusieurs flux en un en un nombre étonnamment élevé de façons.
Les moyens les plus simples qui vous viennent à l'esprit sont de les fusionner dans l'ordre de réception, ou tout d'abord à partir du premier flux, puis à partir du second.
La méthode illustrée ci-dessous dans l'image permet à l'un des deux flux de former un contenant des paires ordonnées d'objets des premier et deuxième flux. Dans ce cas, une nouvelle paire est formée si un nouvel élément apparaît dans l'un des flux. A contient une paire de strictement les derniers éléments de chaque flux. Cela conduit au fait qu'un même élément peut être inclus dans plusieurs paires.
La notation graphique utilisée dans cet exemple est appelée diagrammes de marbre et est très efficace pour expliquer la sémantique du fractionnement et de la fusion des flux.
Si ce sujet vous intéresse, je vous conseille d'étudier les opérations et leurs diagrammes de Marbre sur la ressource [8].


Utilisation de flux


Pour utiliser les éléments du flux, l'utilisateur ou le client doit d'abord s'y abonner. En règle générale, il doit se désinscrire de celui-ci à la fin du traitement, car les garbage collector ne désactivent pas toujours automatiquement un abonnement lorsqu'ils essaient d'utiliser un abonné.
De nombreux clients peuvent s'abonner à un thread. Dans RxJs, la fonction d'abonnement est appelée subscribe (). Dans ce document, dans la plupart des cas, il est conseillé de placer des appels de traitement des éléments "normaux" du flux, d'un gestionnaire d'erreurs et (relativement rarement) d'un gestionnaire de terminaison de flux.
Chacun des abonnés au flux reçoit sa copie de l'élément ou un clone de l'élément d'origine. Afin de ne pas causer de problèmes, le flux est implémenté de telle sorte que les éléments reçus pour le traitement deviennent immuables. Dans certaines situations, cette limitation peut encore être contournée, mais il vaut mieux ne pas le faire.

Charme dangereux des ruisseaux


Les flux sont des objets très compliqués, quelque peu apparentés aux intégrales en mathématiques. C'est une chose de savoir qu'ils existent et même d'imaginer à peu près ce que c'est, et une autre chose de pouvoir les utiliser.
Comprendre la logique interne de leur fonctionnement, nécessaire pour bien les appliquer dans la pratique, nécessite un effort intellectuel considérable.
Les flux sont intrinsèquement étroitement liés à la programmation fonctionnelle. Pour une utilisation compétente des flux, il est utile de comprendre comment il est possible de construire et d'appliquer des fonctions de second ordre - des fonctions pour lesquelles d'autres fonctions servent d'arguments.
Ensuite, la beauté et l'élégance des flux vous seront pleinement révélées.
Les flux sont contagieux. Après avoir compris leur beauté, je veux les utiliser dans toutes les tâches, ce qui bien sûr n'est pas nécessaire.
Dans quelles tâches il est conseillé d'utiliser les flux et où les méthodes traditionnelles doivent être utilisées, chacun décide pour lui-même.

Résumer


Dans cet article, j'ai essayé de vous parler des modèles mentaux de programmation réactive (MM RP) et même de les mettre partiellement dans votre conscience. Répétons encore les points principaux.

  1. MM RP sont spéciaux, pas similaires aux modèles mentaux de la programmation traditionnelle.
  2. Lorsque nous nous lançons dans la programmation réactive, nous devons nous rappeler que certains éléments bien établis dans d'autres domaines du MM tels que le curseur, les chaînes d'appel ou les boucles ne fonctionnent pas, ou ne fonctionnent pas comme ça.
  3. Le modèle mental principal de RP est un «flux à trois canaux» avec un canal pour les éléments «normaux», les erreurs et les informations sur la fin du flux.
  4. Les flux peuvent être finis et infinis.
  5. «», «» «» . «» «».
  6. . (, ). .
  7. , .
  8. , .
  9. . .
  10. , «».


Si ce sujet vous intéresse, vous pouvez "jouer" avec les streams en utilisant les simulateurs disponibles sur le site [8].
Si vous voulez mieux comprendre les concepts de RP, je vous recommande de parcourir le livre [7], et bien sûr, de vous familiariser avec The Reactive Manifesto [11].
Vous atteindrez le niveau suivant dans la formation de votre propre MM RP en travaillant à travers les livres [9] et [10] sur la conception et la modélisation des systèmes réactifs.

Littérature et références


  1. La programmation est la matérialisation des idées. (Article sur Habr. Habr.com/ru/post/425321 )
  2. Sirotin V. RPSE: la réification comme paradigme du génie logiciel. arxiv.org/abs/1810.01904
  3. Programmation événementielle. en.m.wikipedia.org/wiki/Event-driven_programming
  4. Dataflow-programming. en.m.wikipedia.org/wiki/Dataflow_programming
  5. Stream-processing. en.m.wikipedia.org/wiki/Stream_processing
  6. Rx-Extensions: reactivex.io/languages.html
  7. RxJS in Action. – 4. August 2017. Paul P. Daniels (Autor), Luis Atencio. Manning Publications. ISBN-13: 978-1617293412
  8. RxJS online Documentstion. xgrommx.imtqy.com/rx-book/index.html
  9. Reactive Design Patterns. 2017. Roland Kuhn Dr., Brian Hanafee, Jamie Allen. Manning Publications. ISBN-13: 978-1617291807
  10. Functional and Reactive Domain Modeling. 2016. Debasish Ghosh.Manning Publications. ISBN-13: 978-1617292248
  11. The Reactive Manifesto www.reactivemanifesto.org


: geralt

Source: https://habr.com/ru/post/undefined/


All Articles