Skip to content

timestamp - Attacher des horodatages

L'opérateur timestamp attache un horodatage à chaque valeur dans un flux. En enregistrant l'heure exacte à laquelle les valeurs ont été émises, il peut être utilisé pour la mesure des performances, le débogage et l'analyse chronologique des événements.

🔰 Syntaxe et comportement de base

Convertit chaque valeur en un objet avec un horodatage.

ts
import { interval } from 'rxjs';
import { timestamp, take } from 'rxjs';

interval(1000)
  .pipe(
    take(3),
    timestamp()
  )
  .subscribe(console.log);

// Sortie :
// { value: 0, timestamp: 1640000000000 }
// { value: 1, timestamp: 1640000001000 }
// { value: 2, timestamp: 1640000002000 }

L'objet retourné a la structure suivante :

  • value : La valeur originale
  • timestamp : L'horodatage (temps Unix en millisecondes)

🌐 Documentation officielle RxJS - timestamp

💡 Cas d'utilisation typiques

  • Mesure des performances : Mesure du temps de traitement
  • Analyse du timing des événements : Mesure des intervalles entre les actions utilisateur
  • Débogage et journalisation : Enregistrement du moment d'émission des valeurs
  • Enregistrement de données temporelles : Sauvegarde de données de capteurs avec horodatage

🧪 Exemple de code pratique 1 : Mesure des intervalles de clic

Exemple mesurant les intervalles entre les clics de l'utilisateur.

ts
import { fromEvent } from 'rxjs';
import { timestamp, pairwise, map } from 'rxjs';

// Création de l'interface utilisateur
const container = document.createElement('div');
document.body.appendChild(container);

const title = document.createElement('h3');
title.textContent = 'timestamp - Mesure des intervalles de clic';
container.appendChild(title);

const button = document.createElement('button');
button.textContent = 'Cliquez ici';
button.style.marginBottom = '10px';
button.style.padding = '10px 20px';
button.style.fontSize = '16px';
container.appendChild(button);

const output = document.createElement('div');
output.style.border = '1px solid #ccc';
output.style.padding = '10px';
output.style.maxHeight = '250px';
output.style.overflow = 'auto';
container.appendChild(output);

let clickCount = 0;

function addLog(message: string, color: string = '#e3f2fd') {
  const logItem = document.createElement('div');
  logItem.style.padding = '5px';
  logItem.style.marginBottom = '3px';
  logItem.style.backgroundColor = color;
  logItem.textContent = message;
  output.insertBefore(logItem, output.firstChild);
}

fromEvent(button, 'click')
  .pipe(
    timestamp(),
    pairwise(),
    map(([prev, curr]) => {
      const interval = curr.timestamp - prev.timestamp;
      return {
        clickNumber: clickCount + 1,
        interval: interval,
        timestamp: new Date(curr.timestamp).toLocaleTimeString('fr-FR')
      };
    })
  )
  .subscribe(data => {
    clickCount++;
    const color = data.interval < 500 ? '#ffcdd2' :
                  data.interval < 1000 ? '#fff9c4' : '#c8e6c9';

    const speed = data.interval < 500 ? 'Clic rapide !' :
                  data.interval < 1000 ? 'Normal' : 'Lent';

    addLog(
      `${data.clickNumber}e : ${data.interval}ms d'intervalle [${speed}] (${data.timestamp})`,
      color
    );
  });

addLog('Cliquez sur le bouton (mesure à partir du 2e clic)', '#e3f2fd');
  • Mesure précise des intervalles entre les clics
  • Affichage coloré selon la vitesse
  • Enregistrement de l'heure d'occurrence avec l'horodatage

🧪 Exemple de code pratique 2 : Mesure du temps de traitement

Exemple mesurant le temps pris par chaque traitement.

ts
import { interval } from 'rxjs';
import { timestamp, map, take } from 'rxjs';

// Création de l'interface utilisateur
const container2 = document.createElement('div');
container2.style.marginTop = '20px';
document.body.appendChild(container2);

const title2 = document.createElement('h3');
title2.textContent = 'timestamp - Mesure du temps de traitement';
container2.appendChild(title2);

const output2 = document.createElement('div');
output2.style.border = '1px solid #ccc';
output2.style.padding = '10px';
container2.appendChild(output2);

function addLog2(message: string) {
  const logItem = document.createElement('div');
  logItem.style.padding = '3px';
  logItem.style.fontSize = '12px';
  logItem.style.fontFamily = 'monospace';
  logItem.textContent = message;
  output2.appendChild(logItem);
}

addLog2('Début du traitement...');

interval(500)
  .pipe(
    take(5),
    timestamp(),
    map(data => {
      const start = data.timestamp;

      // Simulation d'un traitement lourd (temps de traitement aléatoire)
      const iterations = Math.floor(Math.random() * 5000000) + 1000000;
      let sum = 0;
      for (let i = 0; i < iterations; i++) {
        sum += i;
      }

      const end = Date.now();
      const duration = end - start;

      return {
        value: data.value,
        startTime: new Date(start).toLocaleTimeString('fr-FR', { hour12: false }) +
                   '.' + (start % 1000).toString().padStart(3, '0'),
        duration: duration
      };
    })
  )
  .subscribe({
    next: result => {
      addLog2(
        `Valeur ${result.value} : début=${result.startTime}, temps de traitement=${result.duration}ms`
      );
    },
    complete: () => {
      addLog2('--- Tous les traitements sont terminés ---');
    }
  });
  • Enregistrement de l'heure de début de traitement pour chaque valeur
  • Mesure du temps pris pour le traitement
  • Utilisation pour l'analyse des performances

Utilisation des horodatages

ts
import { of } from 'rxjs';
import { timestamp, map } from 'rxjs';

of('A', 'B', 'C')
  .pipe(
    timestamp(),
    map(data => {
      // Traitement avec l'horodatage
      const date = new Date(data.timestamp);
      return {
        value: data.value,
        time: date.toISOString(),
        unixTime: data.timestamp
      };
    })
  )
  .subscribe(console.log);
// Sortie :
// { value: 'A', time: '2024-01-01T00:00:00.000Z', unixTime: 1704067200000 }
// ...

⚠️ Notes importantes

1. Précision de l'horodatage

Utilise Date.now() de JavaScript, donc la précision est en millisecondes.

ts
import { interval } from 'rxjs';
import { timestamp, take } from 'rxjs';

// Événements à haute fréquence (intervalle de 1ms)
interval(1)
  .pipe(
    take(3),
    timestamp()
  )
  .subscribe(data => {
    console.log(`Valeur : ${data.value}, Horodatage : ${data.timestamp}`);
  });
// Peut avoir le même horodatage

Pour une plus grande précision, envisagez d'utiliser performance.now().

2. L'horodatage est au moment de l'émission

L'horodatage correspond au moment de l'émission de la valeur, pas au moment de sa génération.

ts
import { of, delay, timestamp } from 'rxjs';

of(1, 2, 3)
  .pipe(
    delay(1000),      // Délai de 1 seconde
    timestamp()       // Horodatage après le délai
  )
  .subscribe(console.log);

3. Changement de structure de l'objet

Lorsque vous utilisez timestamp, les valeurs sont enveloppées dans un objet.

ts
import { of, timestamp, map } from 'rxjs';

of(1, 2, 3)
  .pipe(
    timestamp(),
    map(data => data.value * 2)  // Accès à la valeur originale via .value
  )
  .subscribe(console.log);
// Sortie : 2, 4, 6

📚 Opérateurs associés

  • tap - Exécution d'effets secondaires (pour le débogage)
  • delay - Délai fixe
  • timeout - Contrôle du délai d'expiration

✅ Résumé

L'opérateur timestamp attache un horodatage à chaque valeur.

  • ✅ Enregistrement précis de l'heure d'émission de chaque valeur
  • ✅ Efficace pour la mesure des performances
  • ✅ Analyse des intervalles entre événements possible
  • ✅ Utile pour le débogage et la journalisation
  • ⚠️ Précision en millisecondes
  • ⚠️ Les valeurs sont enveloppées dans un objet
  • ⚠️ L'horodatage correspond au moment de l'émission

Publié sous licence CC-BY-4.0.