#rxjs #rxjs6
#rxjs #rxjs6
Вопрос:
Я создаю службу «оповещения». Когда приходит новое предупреждение, я хочу показать предупреждение на время. В течение этого времени я не хочу показывать другие предупреждения, которые могли прийти. Я хочу перейти к следующему оповещению только ПОСЛЕ завершения текущего. Поэтому, по сути, я хочу испустить значение, а затем подождать длительность, прежде чем выдавать следующее значение.
Это может быть представлено как:
const incomingAlerts$ = interval(1000);
const alerts$ = incomingAlerts$.pipe(
concatMap((alert) => alert.pipe(delay(3500)))
);
Это близко к тому, что я хочу, но задержка ожидает, ПРЕЖДЕ чем выдавать значение. Существует ли оператор или возможная настройка, которая будет выдавать значение, а затем ждать, прежде чем выдавать следующее значение (если оно есть)?
Ответ №1:
Я думаю, что это может быть достигнуто с помощью exhaustMap
:
incomingAlerts$.pipe(
exhaustMap(
alert => NEVER
.pipe(
startWith(startAlertAction(alert)),
takeUntil(duration),
endWith(stopAlertAction(alert))
)
)
)
При exhaustMap
этом новая внутренняя наблюдаемая не будет создана, если текущая внутренняя наблюдаемая не станет неактивной (например completes
, / отправляет error
уведомление). Если внутренняя наблюдаемая уже активна, то значение из внешней наблюдаемой будет проигнорировано.
Комментарии:
1. Да, но я не хочу, чтобы те значения, которые будут игнорироваться. Я хочу, чтобы они «ставились в очередь», по существу, для отправки через некоторое время
2. @AveryFerrante что, если вы замените exhaustMap на concatMap в моем примере?
Ответ №2:
Что вам нужно сделать, это создать поток, который выдает значение, ожидает некоторое время, а затем завершается.
Вот довольно странный способ сделать это. Вы устанавливаете a timer
и filter
отключаете его выброс. Теперь у вас есть поток, который ничего не выдает и завершается за 3500 мс. Затем вы startWith
получаете свое предупреждение. Вы можете позволить concatMap
обрабатывать остальное (оно будет буферизировать значения до завершения timer
потока):
const alerts$ = incomingAlerts$.pipe(
concatMap(alert => timer(3500).pipe(
filter(_ => false),
startWith(alert)
))
);