Bonjour à tous,
Un point que je trouve intéressant avec les Web Workers : le calcul peut être terminé alors que l’interface affiche encore ses étapes intermédiaires. Comment empêcher une animation interrompue de revenir modifier l’affichage ?
Sur un petit projet personnel en React, j’ai séparé le dernier état calculé (`state`) de l’état actuellement affiché (`frame`). Le Worker renvoie le résultat et une liste d’événements avec leurs instantanés. L’interface les présente successivement, sans recalculer la logique.
Pour interrompre cette lecture, j’utilise un compteur de génération. Voici le principe, simplifié depuis le hook ; `sequence` est une référence persistante, et `wait` une attente sur timer :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 async function present(update) { const token = ++sequence.current; setState(update.state); for (const event of update.events) { if (token !== sequence.current) return; setFrame(event.state); await wait(450); } if (token !== sequence.current) return; setFrame(update.state); }
Lorsqu’on passe l’animation, le contrôleur incrémente `sequence.current`, débloque l’attente et affiche directement l’état final. L’ancienne boucle ne peut alors plus réafficher un instantané précédent. Le contrôle après la boucle est important : une interruption peut aussi survenir pendant la dernière attente. Au démontage, le nettoyage invalide également la génération.
Les nouvelles commandes restent bloquées pendant le calcul et la lecture. Le compteur invalide uniquement la présentation ; il n’annule pas un calcul dans le Worker.
Cette séparation permet de changer la vitesse ou de sauter les animations sans modifier le résultat. Elle a toutefois un coût : les instantanés transmis par `postMessage` sont copiés par clonage structuré. Pour un historique volumineux, il faudrait mesurer ce coût et envisager des mises à jour plus compactes.






Répondre avec citation
Partager