retour au cours

Stocker les messages non-lus

importance: 5

Il y a un tableau de messages :

let messages = [
  {text: "Hello", from: "John"},
  {text: "How goes?", from: "John"},
  {text: "See you soon", from: "Alice"}
];

Votre code peut y accéder, mais les messages sont gérés par le code d’une autre personne. De nouveaux messages sont ajoutés, les anciens sont régulièrement supprimés par ce code et vous ne connaissez pas le moment exact où cela se produit.

Maintenant, quelle structure de données pouvez-vous utiliser pour stocker des informations si le message “a été lu” ? La structure doit être bien adaptée pour donner la réponse “a-t-il été lu ?” Pour l’objet de message donné.

P.S. Lorsqu’un message est supprimé des messages, il doit également disparaître de votre structure.

P.P.S. Nous ne devrions pas modifier les objets de message, leur ajouter nos propriétés. Comme ils sont gérés par le code de quelqu’un d’autre, cela peut avoir de mauvaises conséquences.

Stockons les messages lus dans WeakSet:

let messages = [
  {text: "Hello", from: "John"},
  {text: "How goes?", from: "John"},
  {text: "See you soon", from: "Alice"}
];

let readMessages = new WeakSet();

// deux messages ont été lus
readMessages.add(messages[0]);
readMessages.add(messages[1]);
// readMessages a 2 éléments

// ...Relisons le premier message !
readMessages.add(messages[0]);
// readMessages a encore 2 éléments uniques

// réponse : le message[0] a-t-il été lu ?
alert("Read message 0: " + readMessages.has(messages[0])); // true

messages.shift();
// maintenant readMessages a 1 élément (techniquement, la mémoire peut être nettoyée plus tard)

Le WeakSet permet de stocker un ensemble de messages et de vérifier facilement l’existence d’un message dedans.

Il se nettoie automatiquement. Le compromis est que nous ne pouvons pas le parcourir, nous ne pouvons pas obtenir “tous les messages lus” directement. Mais nous pouvons le faire en parcourant tous les messages et en filtrant ceux qui sont dans le set.

Une autre solution pourrait consister à ajouter une propriété telle que message.isRead = true à un message après sa lecture. Comme les objets de messages sont gérés par un autre code, cela est généralement déconseillé, mais nous pouvons utiliser une propriété symbolique pour éviter les conflits.

Comme ceci :

// la propriété symbolique n'est connue que de notre code
let isRead = Symbol("isRead");
messages[0][isRead] = true;

Maintenant, le code tiers ne verra probablement pas notre propriété supplémentaire.

Bien que les symboles permettent de réduire la probabilité de problèmes, l’utilisation de WeakSet est préférable du point de vue de l’architecture.