существует ли версия debounce, которая выбирает максимальное значение во временном интервале? (RxJS)

#rxjs #reactivex #debounce

#rxjs #reactivex #удаление

Вопрос:

В основном только заголовок. Я объединил два потока, но они оба излучают один раз в секунду, и я хочу использовать только максимум один в секунду. в моем объединенном потоке содержится два значения в секунду, но мой текущий метод debounce не обращает внимания на то, какое из них больше.

Существуют ли какие-либо решения для этого? (т.Е. Способ передачи функции для debounce)

Вот мой код:

 var a = [11, 12, 14, 15, 18, 20];
var b = [1, 2, 8, 16, 43, 100];

const first = interval(1000).pipe(
  take(a.length),
  map(i => a[i])
);

const second = interval(1000).pipe(
  take(b.length),
  map(i => b[i])
);

const example = first.pipe(merge(second));

const example2 = example.pipe(
  debounce(() => interval(1))
);
  

Я пытался использовать scan и max, но, похоже, они не обладают желаемой функциональностью.

Ответ №1:

Я действительно не уверен в том, чего вы на самом деле хотите, поскольку ваше описание не очень понятно. Итак, я дам вам две возможности, и мы сможем посмотреть, соответствует ли одна из них действительности.

Первый — объединить два потока и выдать только наибольшее значение каждого. Это не требует какого-либо времени и не похоже на debounce. Он просто связывает исходные наблюдаемые.

 zip(first, second).pipe(
  map(([x, y]) => Math.max(x, y))
).subscribe(console.log);
  

Второй подход заключается в буферизации значений в течение секунды, а затем выдает наибольшее из буферизованных значений. Этот подход не объединяет исходные потоки. Неважно, сколько существует потоков или как часто они излучают. Одна секунда может иметь 12 значений, а следующая может иметь 1 значение. Он просто выдаст наибольшее значение.

 merge(first, second).pipe(
  bufferTime(1000),
  filter(buffer => buffer.length > 0),
  map(buffer => Math.max(...buffer))
).subscribe(console.log);
  

Эти два делают очень разные вещи, но, вероятно, имеют аналогичный результат для вашего конкретного случая. Первый ближе к тому, что описывает ваша проблема, а второй ближе к тому, что описывает ваш заголовок.


Кроме того, вот более функциональный подход к созданию ваших первого и второго потоков.

 const first = zip(
  from([11, 12, 14, 15, 18, 20]),
  interval(1000),
  (x, y) => x
);

const second = zip(
  from([1, 2, 8, 16, 43, 100]),
  interval(1000),
  (x, y) => x
); 
  

Добавленное значение здесь заключается в том, что интервал не нужно изменять, считывая переменную из ее закрытия. Здесь он может оставаться «чистым», потому что zip откажется от подписки после завершения потока массива.