debounceTime method

Stream<T> debounceTime(
  1. Duration duration
)

Implementation

Stream<T> debounceTime(Duration duration) {
  late StreamController<T> controller;
  StreamSubscription<T>? subscription;
  Timer? timer;
  T? latest;
  var hasLatest = false;
  var sourceDone = false;

  void emitLatest() {
    if (hasLatest) {
      controller.add(latest as T);
      hasLatest = false;
      latest = null;
    }
    if (sourceDone) controller.close();
  }

  controller = StreamController<T>(
    sync: true,
    onListen: () {
      subscription = listen(
        (event) {
          latest = event;
          hasLatest = true;
          timer?.cancel();
          timer = Timer(duration, emitLatest);
        },
        onError: controller.addError,
        onDone: () {
          sourceDone = true;
          if (timer == null || !timer!.isActive) emitLatest();
        },
      );
    },
    onPause: () => subscription?.pause(),
    onResume: () => subscription?.resume(),
    onCancel: () async {
      timer?.cancel();
      await subscription?.cancel();
    },
  );

  return controller.stream;
}