Может быть, это действительно слишком сложно, может, стоит поискать.
Идея состоит в том, чтобы иметь 2 разных наблюдаемых, созданные преобразованием источника observable$
, а затем в конечном итоге объединенные.
Первый Observable, назовем его obsFilterAndMapped
, - это тот, где вы выполняете фильтрацию и отображение.
Второй Observable, назовем его obsTapDelay
, - это Observable, который запускает новый таймер с определенной задержкой каждый раз, когда излучает первый Observable, то есть obsFilterAndMapped
- как только delayTime передано, то вы выполняете свое tapAfterTime
действие - если первый Observable испускает новое значение до того, как будет передано delayTime, тогда будет создан новый таймер.
Это код, который реализует эту идею
const stop = new Subject<any>();
const obsShared = observable$.pipe(
finalize(() => {
console.log('STOP');
stop.next();
stop.complete()
}),
share()
);
const delayTime = 300;
const tapAfterTime = (value) => {
console.log('tap with delay', value)
};
let valueEmitted;
const obsFilterAndMapped = obsShared.pipe(
tap(val => valueEmitted = val),
filter(i => i > 7),
map(val => val + ' mapped')
);
const startTimer = merge(of('START'), obsFilterAndMapped);
const obsTapDelay = startTimer.pipe(
switchMap(val => timer(delayTime).pipe(
tap(() => tapAfterTime(valueEmitted)),
switchMap(() => empty()),
)),
takeUntil(stop),
)
merge(obsFilterAndMapped, obsTapDelay)
.subscribe(console.log, null, () => console.log('completed'))
При таком подходе вы будете выполнять свое tapAfterTime
действие каждый раз, когда источник observable$
ничего не испускает в течение времени, превышающего delayTime
. Другими словами, это сработает не только для первого выброса observable$
, но и для всей его жизни.
Вы можете протестировать такой код с помощью следующего ввода
const obs1 = interval(100).pipe(
take(10),
);
const obs2 = timer(2000, 100).pipe(
take(10),
map(val => val + 200),
);
const observable$ = merge(obs1, obs2);
Приложив еще немного усилий, мы можем даже подумать о том, чтобы скрыть глобальную переменную valueEmitted
внутри замыкания, но это увеличило бы сложность кода и, вероятно, этого не стоит.
person
Picci
schedule
28.09.2018