Есть ли способ повторять наблюдаемое до тех пор, пока не испустит другое наблюдаемое?

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

тс/rxjs

Я попробовал использовать takeUntil, но это закрывает поток $, но он фактически не завершается (он обрезает его до таймера 1000 мс).

const stream$ = interval(1).pipe(takeUntil(timer(1000)));
stream$.pipe(repeat(), takeUntil(timer(1500)));

Если мы согласны с тем, что поток $ выполняется в течение 1000 мс перед закрытием, я ожидаю, что в этом случае он должен выполняться 2 раза по 1000 мс. Мне нужен какой-то оператор, который перестанет повторять наблюдаемое при каком-то событии$.

Что-то вроде этого:

const stream$ = interval(1).pipe(takeUntil(timer(1000)));
stream$.pipe(repeatUntil(timer(1500)));

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы можем использовать takeWhile и дождаться выброса нулевого элемента, а затем вызвать условие взятия.

Это сгенерирует выходные данные, в которых мы, похоже, получим излучение даже после установленного порогового времени.

const { rxObserver } = require('api/v0.3');
const { timer, interval, Subject  } = require('rxjs');
const { take, map, repeat, takeUntil, takeWhile, toArray} = require('rxjs/operators');

const msg = 'awesome';
let turnOff = true;

interval(33).pipe(
    takeUntil(timer(100)),
    repeat(),
    takeWhile((data) => data === 0 ? turnOff : true),
  ).subscribe(rxObserver());
  
  setTimeout(() => {
    turnOff = false;
  }, 134)

Попробуйте переключить значение setTimeout между 134 и 133.

Диаграмма шариков для приведенного ниже кода — попробуйте на ThinkRx -> используйте приведенный выше код, чтобы увидеть его в действии на этом веб-сайте.

На самом деле это работает не так, как я хочу. Мне нужно повторить один и тот же поток $, от его начала до завершения, и продолжать повторять его до тех пор, пока не произойдет какое-либо внешнее событие $. interval(33).pipe(takeUntil(timer(100))).pipe(repeat()).subs‌​cribe(rxObserver()); Это будет повторять 012, 012, 012, 012... шарики. Когда я хочу остановить это в какой-то момент, я хочу, чтобы он завершил текущий повторяющийся наблюдаемый поток, чтобы он оказался на шарике 2, а не разрезал его на шарике 0 или 1.

Darko Mitic 24.08.2024 12:03

@DarkoMitic обновил мой ответ!

Naren Murali 25.08.2024 01:04

Это интересный подход, и он делает то, что я хочу. В моем случае я бы использовал timer(0, 33) вместо interval(33), чтобы не задерживать нулевую эмиссию, а также суммировать последнюю эмиссию с нулевой эмиссией из следующего цикла. Прежде чем вы предложили мне это решение, я использовал комбинацию повтораКогда и takeUntil с фильтром: repeatWhen(() => trigger$.pipe(filter((repeat) => repeat))), takeUntil(trigger$.pipe(filter((repeat) => !repeat))), но ваш ответ гораздо более элегантен и не требует эмиссии триггера$ в конце каждого цикла. Большое спасибо!

Darko Mitic 25.08.2024 02:42

Другие вопросы по теме