atomrc / callbag-debounce

Debounce ⏱ operator for Callbag 👜
MIT License
12 stars 5 forks source link

Fix lack of timer cleanup when terminated by sink. #13

Closed bjnsn closed 3 years ago

bjnsn commented 3 years ago

Cleans up timer when terminated by sink. This resolves an issue that shows up when using debounce when switching between callbag streams (ala RXJS SwitchMap).

See https://stackblitz.com/edit/typescript-ufcfks?file=index.ts

import { interval, merge, map, forEach, pipe, flatten } from "callbag-basics";
import of from "callbag-of";
import wait from "callbag-wait";
import { debounce } from "callbag-debounce";

pipe(
  // start with 0, then pass 1 after 4 seconds
  merge(
    of(0),
    pipe(
      of(1),
      wait(2000)
    )
  ),
  map(val => {
    if (val === 0) {
      // when 0, pass a stream with some noisy input data
      return pipe(
        // some data that shows up randomly
        merge(interval(1000 / 5), interval(1000 / 6), interval(1000 / 7)),
        // but debounce it
        debounce(111),
        map(val => `noisy ${val}`)
      );
    } else {
      // when 1, pass a stream of 'complete'
      return of("complete");
    }
  }),
  // take the values from the most recent stream
  // ala RXJS switchmap
  flatten,
  // but we recieve a noisy data value after
  // switching to the complete stream because
  // debounce fails to handle the 'terminate'
  // signal from its sink
  forEach(val => console.log(val))
);
atomrc commented 3 years ago

Hey @bjnsn Great thanks for the PR, looks good to me. One thing, though, do you think you could add tests to cover this scenario? That would be awesome!

bjnsn commented 3 years ago

Test submitted!

atomrc commented 3 years ago

Awesome thanks. Will deploy new version very soon 🙏

atomrc commented 3 years ago

Published under v 3.0.0. Thanks again @bjnsn