РЕДАКТИРОВАТЬ: TL; DR
Заменить merge
на concat
и добавить first
в трубу на concat
:
concat(optionOne$, optionTwo$, optionThree$)
.pipe(
first()
);
concat
подписывается последовательно на каждое наблюдаемое, что означает, что optionOne$
подписывается первым, он выдает свои значения, по завершении отписывается от, затем concat
подписывается на optionTwo$
и так далее ...пока все наблюдаемые не завершатся, а затем, наконец, не выдаст все значения в виде массива.Добавление first
просто обрезает этот процесс, так как он завершает concat после первого испущенного значения.
Вам действительно нужно проверить, что все наблюдаемые внутри concat
завершатся, или вы можете получитьусловие, при котором один из них никогда не генерируется или не завершается, и это будет означать, что вы никогда не получите значение, полученное из concat
.
—-
Предполагая, что ваш isSettingValid()
возвращает false, если он не проходит проверку, тогда просто добавьте pipe()
с first()
к concat()
.См. Немного измененную версию ниже, и stackblitz здесь.
Эта статья также информативна.И я предлагаю статью , в которой есть классные картинки для объяснения операторов и их работы - я всегда возвращаюсь к этому, когда пытаюсь понять что-то подобное.
Я думаю, что это отвечает на ваш вопрос, потому что он выдает первое значение, которое проходит проверку и игнорирует остальные.
import { of, Observable, concat } from 'rxjs';
import { take, filter, first } from 'rxjs/operators';
function isSettingValid(setting): boolean {
return setting !== 'error' ? true : false;
}
function getSetting(): Observable<any> {
const optionOne$ = of('error')
.pipe(
take(1),
filter(setting => isSettingValid(setting))
);
const optionTwo$ = of('second')
.pipe(
take(1),
filter(setting => isSettingValid(setting))
);
const optionThree$ = of('default').pipe(
take(1),
filter(setting => isSettingValid(setting))
);
return concat(optionOne$, optionTwo$, optionThree$)
.pipe(
first() // emits only the first value which passes validation then completes
);
}
getSetting()
.subscribe((setting) => {
console.log(setting);
})
Я также предлагаю удалить setting &&
, как в моем фрагменте,и установка нулевой проверки внутри вашей функции проверки - это просто делает фильтр более легким для чтения, если вы делаете это таким образом, imo.Чтобы сделать его более кратким, вы можете рассмотреть замену take(1)
и filter()
на first
и функцию предиката, которая будет иметь тот же результат:
const optionOne$ = of('error')
.pipe(
first(setting => isSettingValid(setting))
);