2017-12-27 285 views
0

我有一个角度服务,我想暴露一个observable,它充当逻辑“或”的类。假设我有多个源序列可以给出onoff的值。我需要输出true任何时候任何东西都是on,并且当所有值为off时返回falserxjs中是否有逻辑或类型的运算符?

例子:

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$),所以这有点不错,但是我的输入不同步,所以并不总是完美的。我的意思是,第一美元可能放出一个以上的价值,而第二美元可能永远不会开火,反之亦然。我还可以做些什么?

我想过一些mergeMap或类似的,然后保持外部上下文的状态,这种方式我运行任何事件的更新。但是当我遇到问题时,“关闭”事件可能意味着“关闭”,但是只有其他序列也是“关闭”的时候,所以它很快就会变得棘手。

+0

您可以使用筛选器操作,放出只有当值匹配根据您的要求, –

+0

那么,什么将是什么样子? – Zlatko

+0

在你的代码中看起来对我来说,一旦输入'打开',没有逻辑将其设置为关闭 –

回答

1

实际上,你给出的答案基本上都是自己:

const result$ = Observable.combineLatest(first$, second$) 
    .map(values => values.some(value => value === '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" 

你当然可以将两者结合起来。

+0

但是不合并最后发射两个值的数组? – Zlatko

+0

并且observable.merge在第一个真实事件上给出'on',然后永远保持'on'。 – Zlatko

+0

哦,但我也需要切换回'假'。我的答案中缺少这一点。 – Zlatko

2

看,如果这是你寻找什么

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)