Skip to content

timer() - Start Emitting Na Vertraging

timer() is een Creation Function die waarden emit na een opgegeven vertragingstijd. Ondersteunt zowel eenmalige als periodieke emissie.

Overzicht

timer() is een flexibele Creation Function die het initiële emissie-moment controleert. Gedrag varieert met aantal argumenten: zowel eenmalige emissie als interval()-achtige periodieke emissie zijn mogelijk.

Signature:

typescript
function timer(
  dueTime: number | Date,
  intervalOrScheduler?: number | SchedulerLike,
  scheduler?: SchedulerLike
): Observable<number>

Officiële Documentatie: 📘 RxJS Official: timer()

Basisgebruik

timer() gedrag verandert met aantal argumenten.

Eenmalige Emissie

Met alleen eerste argument emit het 0 na opgegeven tijd en completet.

typescript
import { timer } from 'rxjs';

// Emit 0 na 3 seconden en complete
const timer$ = timer(3000);

timer$.subscribe({
  next: value => console.log('Waarde:', value),
  complete: () => console.log('Compleet')
});

// Output na 3 seconden:
// Waarde: 0
// Compleet

Periodieke Emissie

Met tweede argument voor interval, emit het periodiek na initiële vertraging.

typescript
import { timer } from 'rxjs';

// Start na 3 seconden, emit dan elke seconde
const timer$ = timer(3000, 1000);

timer$.subscribe(value => console.log('Waarde:', value));

// Output:
// Waarde: 0  (na 3s)
// Waarde: 1  (na 4s)
// Waarde: 2  (na 5s)
// ... (oneindig)

Belangrijke Kenmerken

1. Flexibele Vertraging Specificatie

Vertragingstijd kan als milliseconden nummer of Date object worden opgegeven.

typescript
import { timer } from 'rxjs';

// Specificeer in milliseconden
timer(5000).subscribe(() => console.log('Na 5 seconden'));

// Specificeer met Date object (uitvoeren op specifieke tijd)
const targetTime = new Date(Date.now() + 10000); // Na 10 seconden
timer(targetTime).subscribe(() => console.log('Uitgevoerd op specifieke tijd'));

2. Gedrag Verandert Met/Zonder Tweede Argument

Tweede argument bepaalt of het completet.

typescript
import { timer } from 'rxjs';

// Zonder tweede argument - Emit eenmalig en complete
timer(1000).subscribe({
  next: value => console.log('Eenmalig:', value),
  complete: () => console.log('Compleet')
});

// Met tweede argument - Emit oneindig
timer(1000, 1000).subscribe({
  next: value => console.log('Herhalend:', value),
  complete: () => console.log('Compleet (wordt niet getoond)')
});

IMPORTANT

Met Tweede Argument Completet Het Niet

timer(1000, 1000) met tweede argument emit oneindig zoals interval(). Unsubscription is verplicht.

5. Cold Observable

timer() is een Cold Observable. Elke subscription creëert een onafhankelijke timer.

typescript
import { timer } from 'rxjs';

const timer$ = timer(1000);

console.log('Start');

// Subscription 1
timer$.subscribe(() => console.log('Observer 1'));

// Voeg subscription 2 toe na 500ms
setTimeout(() => {
  timer$.subscribe(() => console.log('Observer 2'));
}, 500);

// Output:
// Start
// Observer 1  (na 1s)
// Observer 2  (na 1.5s - onafhankelijke timer)

NOTE

Cold Observable Kenmerken

  • Bij elke subscription start een onafhankelijke uitvoering
  • Elke subscriber ontvangt zijn eigen datastream
  • Bij elke subscription start een onafhankelijke timer. Zoals interval(), gebruik share() voor sharing indien nodig.

Zie Cold en Hot Observables voor meer details.

Verschil tussen timer() en interval()

Het belangrijkste verschil is het initiële emissie-moment.

typescript
import { timer, interval } from 'rxjs';
import { take } from 'rxjs';

console.log('Start');

// interval() - Start direct (eerste waarde na 1s)
interval(1000).pipe(take(3)).subscribe(value => {
  console.log('interval:', value);
});

// timer() - Geen vertraging (eerste waarde direct)
timer(0, 1000).pipe(take(3)).subscribe(value => {
  console.log('timer:', value);
});

// timer() - Start na 2s vertraging
timer(2000, 1000).pipe(take(3)).subscribe(value => {
  console.log('timer(vertraging):', value);
});
Creation FunctionEerste Emissie TimingGebruik
interval(1000)Na 1sDirect periodieke uitvoering
timer(0, 1000)DirectEerste uitvoering direct
timer(2000, 1000)Na 2sPeriodieke uitvoering met vertraging
timer(2000)Na 2s (eenmalig)Vertraagde uitvoering (eenmalig)

Praktische Gebruikssituaties

1. Vertraagde Uitvoering

Voer verwerking eenmalig uit na bepaalde tijd.

typescript
import { from, timer } from 'rxjs';
import { switchMap } from 'rxjs';

function delayedApiCall() {
  return timer(2000).pipe(
    switchMap(() => from(
      fetch('https://jsonplaceholder.typicode.com/posts/1')
        .then(res => res.json())
    ))
  );
}

delayedApiCall().subscribe(data => {
  console.log('Data opgehaald na 2 seconden:', data);
});

2. Polling Met Vertraging

Start polling niet direct maar na bepaalde tijd.

typescript
import { from, timer } from 'rxjs';
import { switchMap, retry } from 'rxjs';

interface Status {
  status: string;
  timestamp: number;
}

// Start polling na 5s, daarna elke 10s
const polling$ = timer(5000, 10000).pipe(
  switchMap(() => from(
    fetch('https://jsonplaceholder.typicode.com/users/1')
      .then(res => res.json() as Promise<Status>)
  )),
  retry(3) // Retry tot 3x bij fouten
);

const subscription = polling$.subscribe(data => {
  console.log('Status update:', data);
});

// Stop indien nodig
// subscription.unsubscribe();

3. Timeout Verwerking

Timeout als verwerking niet binnen tijd compleet.

typescript
import { timer, race, from } from 'rxjs';
import { map } from 'rxjs';

function fetchWithTimeout(url: string, timeoutMs: number) {
  const request$ = from(fetch(url).then(res => res.json()));
  const timeout$ = timer(timeoutMs).pipe(
    map(() => {
      throw new Error('Timeout');
    })
  );

  // Neem welke eerste compleet
  return race(request$, timeout$);
}

fetchWithTimeout('https://jsonplaceholder.typicode.com/posts/1', 3000).subscribe({
  next: data => console.log('Data opgehaald:', data),
  error: err => console.error('Fout:', err.message)
});

4. Automatisch Verbergen Notificaties

Verberg notificaties automatisch na bepaalde tijd.

typescript
import { timer, Subject, map } from 'rxjs';
import { switchMap, takeUntil } from 'rxjs';

interface Notification {
  id: number;
  message: string;
}

const notifications$ = new Subject<Notification>();
const dismiss$ = new Subject<number>();

notifications$.pipe(
  switchMap(notification => {
    console.log('Toon notificatie:', notification.message);

    // Auto-verberg na 5 seconden
    return timer(5000).pipe(
      takeUntil(dismiss$), // Stop bij handmatige verberg
      map(() => notification.id)
    );
  })
).subscribe(id => {
  console.log('Verberg notificatie:', id);
});

// Toon notificatie
notifications$.next({ id: 1, message: 'Nieuw bericht ontvangen' });

// Handmatig verbergen
// dismiss$.next(1);

Gebruik in Pipelines

timer() wordt gebruikt als startpunt voor vertraagde verwerking of periodieke uitvoering.

typescript
import { timer } from 'rxjs';
import { map, take, scan } from 'rxjs';

// Countdown timer (10 tot 0 seconden)
timer(0, 1000).pipe(
  map(count => 10 - count),
  take(11), // 0 tot 10 (11 waarden)
  scan((acc, curr) => curr, 0)
).subscribe({
  next: time => console.log(`Resterend: ${time} seconden`),
  complete: () => console.log('Timer afgelopen')
});

// Output:
// Resterend: 10 seconden
// Resterend: 9 seconden
// ...
// Resterend: 0 seconden
// Timer afgelopen

Veelgemaakte Fouten

1. Vergeten Unsubscriben Met Tweede Argument

typescript
// ❌ Fout - Met tweede argument loopt oneindig
import { timer } from 'rxjs';

function startTimer() {
  timer(1000, 1000).subscribe(value => {
    console.log('Waarde:', value); // Loopt voor altijd
  });
}

startTimer();

// ✅ Correct - Bewaar subscription, unsubscribe indien nodig
import { timer, Subscription } from 'rxjs';
import { take } from 'rxjs';

let subscription: Subscription | null = null;

function startTimer() {
  subscription = timer(1000, 1000).pipe(
    take(10) // Auto-complete na 10x
  ).subscribe(value => {
    console.log('Waarde:', value);
  });
}

function stopTimer() {
  if (subscription) {
    subscription.unsubscribe();
    subscription = null;
  }
}

startTimer();

2. Verschil Met interval() Niet Begrijpen

typescript
// ❌ Verwarring - interval() start direct (eerste waarde na 1s)
import { interval } from 'rxjs';

interval(1000).subscribe(value => {
  console.log('interval:', value); // Output na 1s
});

// ✅ timer() - Eerste waarde direct zonder vertraging
import { timer } from 'rxjs';

timer(0, 1000).subscribe(value => {
  console.log('timer:', value); // Output direct
});

Prestatieoverwegingen

timer() is lichtgewicht, maar gebruik kan prestatie beïnvloeden.

TIP

Optimalisatie Tips:

  • Gebruik geen tweede argument voor eenmalige uitvoering
  • Unsubscribe indien niet meer nodig
  • Deel met share() bij meerdere observers
  • Wees voorzichtig met korte intervallen (100ms of minder)
typescript
import { timer } from 'rxjs';
import { share } from 'rxjs';

// ❌ Prestatieproblemen - Meerdere onafhankelijke timers
const timer$ = timer(0, 1000);

timer$.subscribe(value => console.log('Observer 1:', value));
timer$.subscribe(value => console.log('Observer 2:', value));
// Twee timers lopen parallel

// ✅ Optimalisatie - Deel één timer
const sharedTimer$ = timer(0, 1000).pipe(share());

sharedTimer$.subscribe(value => console.log('Observer 1:', value));
sharedTimer$.subscribe(value => console.log('Observer 2:', value));
// Eén timer wordt gedeeld

Gerelateerde Creation Functions

FunctionVerschilGebruik
interval()Start direct (geen vertraging)Periodieke uitvoering zonder vertraging
of()Emit synchroon directGeen async nodig
defer()Lazy verwerking bij subscriptionDynamische waardegeneratie

Samenvatting

  • timer() is Creation Function die start emitting na vertraging
  • Zonder tweede argument: Eenmalige emissie (compleet)
  • Met tweede argument: Periodieke emissie (compleet niet)
  • Vertragingstijd specificeerbaar als milliseconden of Date object
  • Ideaal voor vertraagde uitvoering, polling met vertraging, timeout verwerking

Volgende Stappen

Uitgebracht onder de CC-BY-4.0 licentie.