Ecrit par Nathanael Cherrier

Découverte du reactive programming : ReactiveX

Publié dans , , , ,

Partagez l'article

twitter facebook

Cela fait un moment que je cherche à en apprendre un peu plus sur la programmation réactive et tout particulièrement ReactiveX. J'ai trouvé un peu de temps pour ça et ce que j'ai appris m'a bien plu.

Qu'est ce que ReactiveX ?

Pour commencer voyons quelques patterns intéressants.

Le pattern Observer

C'est un design pattern assez vieux et très connu. Il a été très utilisé dans des langages comme Java, C#.NET, etc; notamment grâce à des framework qui l'ont pleinement utilisé.

Il permet de gérer, en gros, des événements. Le principe est le suivant.

J'ai des objets "observables" et des objets "observateurs". Lorsqu'ils ont effectué une certaine action, qu'il y a un changement d'état, ou plus simplement que quelque chose s'est passé dans un objet observable, cet objet observable va notifier ses observateurs du changement.

Ils vont donc lancer / appeler les observateurs au moment le plus opportun.

Le pattern Iterator

Là aussi : c'est un design pattern assez connu et plutôt classique. Vous l'avez forcément déjà utilisé même sans vous en rendre compte.

Ce pattern permet d'accéder simplement aux éléments d'un objet "agrégateur" sans exposer son fonctionnement. Il est très souvent implémenté par défaut dans les langages de programmation.

Si vous avez pensé aux tableaux comme une implémentation de ce design pattern, vous n'avez pas faux. Un tableau de string est bien un objet qui agrège plusieurs string. On peut itérer sur le tableau.

Le tableau est un type natif d'agrégateur mais vous n'êtes clairement pas limité à ça. Vous pouvez créer vos propres agrégateurs Iterable. D'ailleurs les structures itératives (for, for...of, for...in, etc), dans la plupart des langages, ne bouclent pas sur les tableaux mais bien sur les Iterable, qu'ils soient des tableaux ou pas. Les tableaux n'étant que des objets implémentant le contrat Iterable.

Le functional programming

La programmation peut-elle se libérer du style de von Neumann ? : un style fonctionnel et son algèbre des programmes — John Backus

La programmation fonctionnelle, comme le laisse penser cette citation, est très inspirée des mathématiques. C'est une façon de programmer très ancienne mais qui revient un peu à la mode.

J'en ai déjà un peu parlé dans de précédents articles. C'est une façon de programmer que j'affectionne beaucoup car elle permet de réduire les effets de bord.

Je vous expose le principe : une fonction prend des paramètres en entrée et retourne un résultat.

f(x) = x + 2 // math
(x) => x + 2 // javascript

En programmation fonctionnelle, une fonction ne doit rien faire d'autre. C'est ce qu'on appelle aussi des pure functions lorsqu'on l'utilise dans un langage non fonctionnel.

Vous ne voyez pas la différence avec une fonction normale ? Une pure function ne modifie pas les variables qui lui sont passé en paramètre, elle ne lance pas de traitement en taches de fond, elle ne modifie pas d'objet. Il ne doit y avoir aucun effet de bord. Une pure function ne fait que ce qu'on lui demande, rien d'autre.

x => {
  console.log(x)
  return x + 2
}

Cette fonction n'est pas une pure function.

ReactiveX

ReactiveX est une API qui se présente comme étant "une combinaison des bonnes idées du pattern Observer, du pattern Iterator et de la programmation fonctionnelle".

Chose intéressante, ReactiveX n'est qu'une API. Elle possède par contre des implémentations dans beaucoup de langage connus et très utilisés.

Je vous mets ceux qui m'intéressent mais n'hésitez pas à regarder dans la doc pour savoir si votre langage préféré possède aussi une implémentation officielle de ReactiveX.

Pour ceux qui se demande où est la programmation réactive (reactive programming) dans cet article mis à part le titre : elle est dans le pattern Observer. La programmation réactive à été inventé pour pallier certaines faiblesses du pattern Observer.

Ce dernier étant sûrement plus connu et servant de base au précédent, les développeurs ont peut-être jugé préférable de mentionner "the Observer pattern" sur leur site plutôt que "the reactive programming".

Quel est le principe de ReactiveX ?

ReactiveX veut que l'on utilise certains types d'objet comme s'il s'agissait d'Iterable qui tiennent compte du temps.

C'est peut-être un peu flou dit comme cela mais réfléchissons : si nous pouvons itérer sur une suite de valeur de même type, pourquoi ne pas itérer sur une suite d'événements ? Ce sont aussi des valeurs de même type.

Le seule déférence est la variable temps. Nous ne savons pas quand un événement va être déclenché — ou en d'autre terme, quand un événement va être ajouté à la suite de notre itérable — d'où l'intérêt que notre itérable soit aussi un observable.

Voilà le principe de ReactiveX. Il veut nous permettre d'itérer sur une suite de valeur non-necesserairement synchrone.

fonction .map()

Comment s'utilise ReactiveX ?

Après tout ce que l'on vient de dire, je pense que vous avez une petite idée, même vague, de ceux à quoi va ressembler le code.

Si l'on reprend le tableau de base en Javascript, quelle action itérative allons-nous pouvoir lui appliquer ? Il y en a énormément mais les principales sont :

tableau
  .map(x => x) // modification
  .filter(x => true) // filtre

Ces méthodes sont purement fonctionnelles. Le résultat est bien une version modifiée de tableau mais tableau n'a pas été modifié par les deux méthodes. Elle retourne un nouvel objet Array qui respecte les conditions que nous lui passons en prenant pour base tableau.

Restons donc sur ce type de méthode, mais itérons sur des événements.

const src = Observable.fromEvent(document, 'click')

src
  .map(e => e.target.id)
  .filter(id => id % 2 === 0)


src.subscribe(val => console.log(val))

On ajoute un observer à l'événement click du document. On ne tient compte que des clicks sur des éléments dont l'id est pair. Et on affiche.

Ce code n'affiche l'id de l'élément cliqué que si celui-ci est pair.

Conclusion

Vous voyez la puissance de ce code ?

On utilise les même méthodes que pour un tableau, elles ont le même but que celles d'un tableau, leur fonctionnement ne changent pas. On l'a fait aussi simplement que pour un tableau.

Sauf que nous ne traitions pas réellement un tableau mais belle est bien un évênement ! La constante temps est prise en compte.

J'espère que la programmation réactive est un peu plus claire pour vous et que cette introduction vous aura plu.

Si vous avez des questions ou des remarques/conseils, n'hésitez pas à m'envoyer un tweet! Et si vous aimez l'article, n'oubliez pas de le partager avec vos amis.