
Partager:
Kelly J. Andrews est un défenseur des développeurs pour Nexmo. Il bricole des ordinateurs depuis plus de 30 ans et a utilisé BASIC pour la première fois à l'âge de 5 ans.
Ce n'est que lorsqu'il a créé sa première page web en 1997 et qu'il a essayé JavaScript pour la première fois qu'il a trouvé sa véritable vocation. Kelly se bat désormais pour JavaScript, un code testable et une livraison rapide.
Vous pouvez le trouver en train de chanter au karaoké, de faire de la magie ou d'encourager les Cubs et les Fighting Irish.
Apprendre et appliquer XState avec Vonage Video
Temps de lecture : 14 minutes
Au cours des derniers mois, j'ai entendu parler de plus en plus de machines à états utilisées pour le développement frontal. L'idée d'une machine à états est qu'elle ne possède qu'un nombre fini d'états et ne peut se trouver que dans un seul état à un moment donné. D'un point de vue conceptuel, cela est parfaitement logique pour le développement d'applications - il n'y a qu'un certain nombre d'états disponibles.
Le concept de machines à états et de diagrammes d'états n'est pas nouveau, et il n'est pas non plus enraciné dans le développement frontal. Il s'agit d'un modèle mathématique, utilisé dans de nombreuses choses autour de nous. Par exemple, une lumière peut être OFF ou ON. On peut décrire n'importe quoi avec une machine à états, même s'il s'agit d'un exemple simple.
On and off states of lightbulb
Introduction à XState
L'utilisation d'une machine à états dans le développement d'applications frontales est devenue beaucoup moins compliquée avec la création du package XState. XState nous aide à définir des machines à états, à créer des événements et des effets, et à contrôler l'ensemble du flux de l'application. XState utilise des méthodes et des objets JavaScript pour décrire la machine à états.
L'exemple de l'ampoule électrique ci-dessus s'écrirait comme suit :
const lightBulb = Machine({
id: 'lightBulb',
initial: 'off',
states: {
off: {
on: {
TURN_ON: 'on'
}
},
on: {
on: {
TURN_OFF: 'off',
}
}
}
});La machine à états définie ici montre les deux états de l'ampoule, OFF et ONet les transitions entre les événements TURN_ON et TURN_OFF.
L'objet lui-même n'est pas très complexe à lire, mais au fur et à mesure que la machine à états se complexifie, il peut être plus difficile à comprendre. XState a créé un outil pour aider à cela - le XState visualizer.
L'utilisation du visualisateur XState permet de voir comment les machines à états fonctionnent et sont interactives, de sorte qu'il est amusant de jouer avec elles. Si vous souhaitez consulter le code de la machine, vous pouvez également cliquer sur le bouton code pour y jeter un coup d'œil.
Création d'un diagramme d'état de Vonage Video
Lorsque j'ai entrepris d'apprendre les machines à états et XState, mon objectif global était de construire une application similaire à Google Meet en utilisant Vonage Video. L'application permettrait à un utilisateur de créer une salle de réunion, de partager l'URL et d'organiser une réunion avec plusieurs flux. Pour en arriver là, j'ai dû apprendre certains des différents concepts des diagrammes d'état et comment les représenter dans XState.
Réfléchir aux états d'application possibles n'est pas une tâche facile, je l'ai constaté. Il y a de nombreuses possibilités à explorer et, en fin de compte, il faut procéder par essais et erreurs pour trouver la bonne solution.
Le reste de cet article couvre quelques concepts de base et construit une visualisation de diagramme d'état qui imitera l'éventuelle machine d'état. Je fournirai également quelques liens et ressources supplémentaires afin que vous puissiez explorer par vous-même.
États et nœuds d'états
A état est une représentation d'une machine à un moment donné. Ce moment peut être défini et transformé en un nœud d'état dans XState, capturé comme une configuration.
Dans mon In-App Video, il y a plusieurs solutions possibles, mais j'ai constaté que décrire les états en termes aussi simples que possible est le meilleur moyen d'obtenir un résultat utile.
Création d'une machine utilise le modèle suivant :
const machine = Machine(state_nodes, options)En gardant à l'esprit une machine à états vidéo, il existe deux états composés - connected et disconnected.
Les nœuds à deux états peuvent sembler trop simplifiés, mais il n'y a que deux états après quelques essais et erreurs. Chacun de ces états est cependant plus complexe qu'un nœud atomique (sans enfant). Au lieu de créer tous les états possibles au niveau supérieur, XState nous aide à organiser les nœuds d'état hiérarchiques et parallèles.
Nœuds d'état hiérarchiques
XState permet de créer des états imbriqués appelés hierarchical nœuds d'état. Lorsque nous démarrons la machine pour la première fois, nous pouvons lui attribuer la valeur idle car la machine sera prête mais ne fera rien. Pourquoi ne pas simplement créer un autre nœud d'état atomique de premier niveau ?
L'ajout d'états au niveau supérieur est appelé "explosion d'états" et constitue un effet secondaire typique des machines à états finis. Étant donné que Vonage Video est encore techniquement disconnectedl'imbrication idle est logique puisque la Video est à la fois déconnectée et inactive. Un autre disconnected devrait être ready. L'état disconnected.ready se produirait juste avant de passer à l'état connected . La machine à états possède également un nœud d'état entre idle et ready pour tout mettre en place. Cet état intermédiaire peut être appelé init phase.
La machine à états se présente maintenant comme suit :
Vous remarquerez que nous n'avons actuellement aucun moyen de passer d'un nœud à l'autre. Nous aborderons les événements et les actions dans un instant.
Nœuds d'état parallèles
A parallel nœud d'état permet à l'application de se trouver dans tous ses sous-états en même temps. La machine d'état de Vonage Video est fortement axée sur les événements, c'est pourquoi nous devons gérer plusieurs états à la fois.
Pour spécifier qu'un nœud d'état est parallèle, nous utilisons type:parallel dans la configuration. Après la transition vers connected, trois états parallèles se produiront - session, publisher, et subscribers. Chacun de ces états mettra en place des événements et des récepteurs d'événements pour contrôler les réponses du service Video de Vonage.
La visualisation qui en résulte ressemble à ceci :
Grâce à ces états primaires, nous pouvons contrôler ce que notre application affiche à certains moments. Cependant, il nous est actuellement impossible de passer d'un état à l'autre. Jetons un coup d'œil aux événements et aux transitions.
Événements et transitions
Étant donné qu'un nœud d'état n'est que la configuration d'un état individuel, il n'y a pas de moyen de passer d'un état à l'autre sans le déclarer dans le nœud d'état.
Chaque nœud est à l'écoute d'un événement pour transition à l'état suivant. Dans l'exemple de l'ampoule, l'événement TURN_ON envoyé indique à la machine de passer à l'état on.
Les transitions ne se produisent qu'entre les nœuds de niveau supérieur et à l'intérieur des nœuds hiérarchiques. Les nœuds parallèles ne sont pas autorisés à effectuer des transitions entre eux. Pour notre application In-App Video, cela signifie ce qui suit :
Lorsque la page est prête, nous pouvons envoyer un
STARTévénement. Cet événement fera passer l'état àdisconnected.init.L'état
disconnected.initsera supprimé une fois que l'événementVIDEO_ELEMENT_CREATEDs'est déclenché.Une fois que nous avons atteint
disconnected.readynous pouvons permettre à l'utilisateur de se connecter, en envoyant l'événementCONNECTet passer àconnected.Si l'application passe l'événement
DISCONNECTl'automate d'état se déconnecte.
La déclaration d'un événement et d'une transition dans XState utilise le modèle suivant :
on: {
EVENT_DESCRIPTOR: 'nextState'
}Vous pouvez également ajouter des actions spécifiques à la transition. Je vous recommande de lire les sections sur les les transitions internes et externes dans la documentation. Elles couvrent en détail les différents types de transitions possibles.
Transitions surveillées
Vous avez peut-être remarqué que l'une des transitions comporte un nœud cond dans la transition. Ce nœud conditionnel est ce qu'on appelle une guarded transition. Les transitions protégées permettent d'éviter que la machine ne passe à un état qui n'est pas autorisé sous certaines conditions. Dans ce cas, je ne veux pas passer à l'état ready tant que le jeton et l'élément Video n'ont pas été créés.
on: {
'VIDEO_ELEMENT_CREATED': {
target: 'ready',
cond: 'checkToken'
}
}La condition de garde checkToken est une référence nommée à l'objet guards dans le paramètre options envoyé à la machine :
const video = Machine(
state_nodes,{
guards: {
checkToken: () => true
}
});
Contexte
Afin d'être plus utile à une application, notre machine à états aura besoin d'un état à vie plus longue, appelé état extended stateou context. L'objet contexte se met à jour en utilisant divers effets avec la assign() La méthode.
En parlant d'actions, nous allons nous y atteler maintenant et terminer le reste du squelette.
Actions et services
Il existe ce que l'on appelle des "effets secondaires" dans les machines à états, que XState classe dans l'une des deux catégories suivantes :
"L'effet n'envoie pas d'événements.
Invoqué - lorsque des événements d'envoi sont requis
Actions
Les actions sont des effets uniques et tendent à être l'un des effets les plus courants dans la machine d'état vidéo. Vous pouvez utiliser les actions lorsque vous entrez ou sortez d'un nœud, ou pendant une transition. Il est extrêmement important de comprendre l'ordre des actions.
Une excellente ressource pour apprendre l'ordre d'action (et tous les sujets sur XState) est une vidéo publiée par. @kyleshvlin sur Egghead.io. Elle m'a aidé à comprendre comment les actions se déclenchent.
L'essentiel des actions de cette machine consiste à mettre à jour le contexte en tant que transition. Lorsque des événements sont appelés, nous pouvons utiliser l'action pour exécuter la assign() méthode :
on: {
'SOME_EVENT': {
actions: assign({'someContext': (ctx, e) => e.someValue})
}
}
Services
Les services invoqués sont l'autre effet principal de la machine d'état vidéo. Pour utiliser les promesses et les écouteurs d'événements, vous devez invoquer un service. Ce concept a été, de loin, le plus difficile à saisir pour moi. La principale difficulté que j'ai dû surmonter a été de comprendre qu'un service invoqué s'arrête lorsque l'état se termine. Si vous effectuez une transition trop rapide, votre promesse ou votre callback disparaîtra.
Il y a deux services principaux que j'utilise dans la machine d'état vidéo, les promesses et les rappels. Le service invoke promises service permet à la machine d'état d'utiliser une promesse pour la résoudre ou la rejeter, puis d'agir en conséquence. Je l'ai utilisé pour interagir avec le serveur de manière asynchrone et mettre à jour le contexte une fois l'opération terminée.
La signature des fonctions des promesses invoquées se présente comme suit :
src: (context, event) => new Promise((resolve, reject) => {
if (event.error) reject('Rejected')
resolve('Resolved')
}),
onDone: {/*success transition*/}
onError: {/*error transition*/}
La deuxième partie de cette machine, et probablement la plus importante, est le système d'alimentation en eau. invoked callbacks. L'architecture de Vonage Video repose fortement sur les événements et les récepteurs d'événements. Dans une machine d'état, ces derniers sont mis en place par le biais d'un rappel. Laissez-moi vous montrer un exemple :
invoke: {
id: 'initPublisher',
src: (ctx) => (cb) => {
let publisher = initPublisher(pubOptions);
publisher.on('videoElementCreated', (e) => {
cb({ type: 'VIDEO_ELEMENT_CREATED', publisher: publisher })
})
return () => publisher.off('videoElementCreated');
}
}
La signature de la fonction d'un rappel invoqué ressemble à ceci :
src: (context, event) => (callback, onReceive) => {
callback('EVENT');
onReceive(event) => { callback('OTHER_EVENT') };
return () => cleanup()
};
En utilisant les actions et les services, notre machine à états Vonage Video ressemble maintenant à ce qui suit :
N'oubliez pas de cliquer autour, et de cliquer sur l'onglet code pour voir à quoi ressemble la machine d'état en tant que configuration.
Ressources et synthèse
Ok - vous êtes arrivé jusqu'ici.
I'm proud of you!
Si c'est la première fois que vous regardez XState, c'est beaucoup à assimiler d'un seul coup. Je continue d'explorer et d'apprendre de nouvelles façons de faire les choses. Ce billet n'est qu'une petite partie de ce qui existe. Pendant que vous apprenez, voici quelques excellentes ressources que vous voudrez consulter
N'hésitez pas à nous contacter si vous avez des questions sur XState, et nous pourrons apprendre quelque chose de nouveau ensemble !
Partager:
Kelly J. Andrews est un défenseur des développeurs pour Nexmo. Il bricole des ordinateurs depuis plus de 30 ans et a utilisé BASIC pour la première fois à l'âge de 5 ans.
Ce n'est que lorsqu'il a créé sa première page web en 1997 et qu'il a essayé JavaScript pour la première fois qu'il a trouvé sa véritable vocation. Kelly se bat désormais pour JavaScript, un code testable et une livraison rapide.
Vous pouvez le trouver en train de chanter au karaoké, de faire de la magie ou d'encourager les Cubs et les Fighting Irish.