rxjs 中有逻辑或类型运算符吗?
Is there a logical-or-type operator in rxjs?
我有一个 angular 服务,我想在其中公开一个充当逻辑 'or' 类型的可观察对象。假设我有多个可以给出 on
和 off
值的源序列。我需要在任何时候输出 true
任何时候 on
,当所有值都是 off
.
时返回 false
示例:
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',所以它很快就会变得棘手。
其实基本上是你自己给出的答案:
const result$ = Observable.combineLatest(first$, second$)
.map(values => values.some(value => value === 'on'));
so that is somewhat ok, but my inputs are out of sync, so it's not always perfect.
老实说,我不明白你的意思。您在问题中明确表示您想要这个:
I need to output true any time anything is on.
因此,如果输入随着时间延迟而变化,您将得到一个中间结果状态。这与你的问题完全一致。
如果您想以某种方式等待所有输入发生变化,因为它们可能会同时发生变化,您可以向其中添加一个 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)
我有一个 angular 服务,我想在其中公开一个充当逻辑 'or' 类型的可观察对象。假设我有多个可以给出 on
和 off
值的源序列。我需要在任何时候输出 true
任何时候 on
,当所有值都是 off
.
false
示例:
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',所以它很快就会变得棘手。
其实基本上是你自己给出的答案:
const result$ = Observable.combineLatest(first$, second$)
.map(values => values.some(value => value === 'on'));
so that is somewhat ok, but my inputs are out of sync, so it's not always perfect.
老实说,我不明白你的意思。您在问题中明确表示您想要这个:
I need to output true any time anything is on.
因此,如果输入随着时间延迟而变化,您将得到一个中间结果状态。这与你的问题完全一致。
如果您想以某种方式等待所有输入发生变化,因为它们可能会同时发生变化,您可以向其中添加一个 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)