Есть ли в rxjs оператор логического типа?

У меня есть угловая служба, где я хочу раскрыть наблюдаемое, которое действует как своего рода логическое "или". Скажем, у меня есть несколько исходных последовательностей, которые могут дать on а также off ценности. Мне нужно вывести true в любое время onи вернитесь к false когда все значения off,

Пример:

const replaceInput = input => input === 'on' ? 'off' : 'on';
const getSource = (name) => Observable.interval(1000)
    .scan(
        input => Math.random() > 0.5 ? replaceInput(input) : input,
        'off' // initial value
    )
    .do(val => console.log(`${name}: ${val});

const first$ = getSource('first');
const second$ = getSource('second');
const result$ = ???;

Теперь я попробовал с result$ = Observable.merge(first$, second$), но это дает всегда on, Я также пытался с result$ = combineLatest(first$, second$), так что это несколько хорошо, но мои входы не синхронизированы, так что это не всегда идеально. Я имею в виду, что first$ может испускать более одного значения, в то время как second может никогда не сработать, и наоборот. Что еще я могу сделать?

Я думал о каком-то mergeMap или подобном, а затем сохранял состояние во внешнем контексте, чтобы я запускал обновления для любого события. Но затем я попадаю в проблему: событие "off" может означать "off", но только если другие последовательности также "off", поэтому это быстро становится сложным.

2 ответа

Решение

Вы на самом деле дали ответ в основном сами:

const result$ = Observable.combineLatest(first$, second$)
  .map(values => values.some(value => value === 'on'));

так что это несколько хорошо, но мои входы не синхронизированы, так что это не всегда идеально.

Я не понимаю, что вы имеете в виду, если честно. Вы четко заявили в своем вопросе, что хотите этого:

Мне нужно выводить true каждый раз, когда что-то включено.

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

Если вы хотите подождать, пока все входные данные изменятся, потому что они могут измениться примерно в одно и то же время, вы можете добавить debounceTime к нему:

const result$ = Observable.combineLatest(first$, second$)
  .debounceTime(100)
  .map(values => values.some(value => value === 'on'));

Или если вы хотите подавить false Выбросы, просто отфильтруйте их:

const result$ = Observable.combineLatest(first$, second$)
  .map(values => values.some(value => value === 'on'))
  .filter(Boolean); // sneaky trick; you can also use "value => value"

Конечно, вы можете объединить оба.

Посмотреть, если это то, что вы ищете

let randomInput=()=>Rx.Observable.interval(1000)
.map(()=>Math.random()>0.5?'on':'off')
.startWith('off')
.map(value=>value==='on'?true:false)

Rx.Observable.combineLatest(randomInput(),randomInput())
.map(([first,second])=>first||second).subscribe(console.log)
Другие вопросы по тегам