← Alle AufgabenNode.js · Middle

Ein Cache mit Lebensdauer (TTL)

Schreib createTtlCache({ ttlMs, now }) mit get, set(key, value, ttl?), has, delete und size. Ein Eintrag lebt ttl Millisekunden (standardmäßig ttlMs) ab seinem letzten set; sobald now() >= expiresAt gilt, ist er abgelaufen.

Abgelaufene Einträge werden nicht geliefert und beim Zugriff entfernt, und size() zählt nur lebende. has muss auch für die Werte 0, null oder "" funktionieren. Die Zeit kommt von now(), der Cache lässt sich also ohne Warten testen.

Tests (5)

  1. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('a', 1);
    expect(cache.get('a')).toBe(1);
    t = 999;
    expect(cache.get('a')).toBe(1);
    t = 1000;
    expect(cache.get('a')).toBe(undefined);
  2. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('short', 'x', 100);
    cache.set('long', 'y');
    t = 500;
    expect(cache.has('short')).toBe(false);
    expect(cache.has('long')).toBe(true);
  3. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('a', 1);
    t = 800;
    cache.set('a', 2);
    t = 1500;
    expect(cache.get('a')).toBe(2);
  4. let t = 0;
    const cache = createTtlCache({ ttlMs: 100, now: () => t });
    cache.set('a', 1); cache.set('b', 2); cache.set('c', 3, 1000);
    expect(cache.size()).toBe(3);
    t = 200;
    expect(cache.size()).toBe(1);
  5. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('zero', 0);
    cache.set('empty', null);
    expect(cache.has('zero')).toBe(true);
    expect(cache.has('empty')).toBe(true);
    expect(cache.has('missing')).toBe(false);
    expect(cache.delete('zero')).toBe(true);
    expect(cache.has('zero')).toBe(false);