问题:
我有多个条件要检查。其中一些导致相同的可观察性。
流程如下:
是否有一种方法可以避免导致相同结果但被粘贴的多个条件?
现在看起来像这样
iif(
() => this.savedLocally,
this.showText1(),
this.checkOnServer().pipe(
switchMap(onServer => iif(
() => onServer,
this.showText2(),
this.showText1()
))
)
)
如果还有一个条件,那么在某处重复this.showText1()
就会有一个条件。
我正在寻找的是重新设计这种逻辑,以减少重复。
诀窍在于,我需要执行三项检查(仅当前一项具有预期结果时才执行下一项检查),并且所有这些检查都是异步的。
如果很简单if
,我会使用if (cond1 && cond2 && cond3)
,但是这里并不是那么简单。我对检查有严格的要求,每项检查都取决于先前的结果。
答案 0 :(得分:0)
您是否绝对需要使用观测值?看起来您也许可以使用简单的异步函数更简洁地编写此代码
async () => {
if(this.savedLocally) return this.showText1();
const isOnServer = await this.checkOnServer();
if(isOnserver) return this.showText2();
const isAnotherCondition = await this.checkAnotherCondition();
if(isAnotherCondition ) return this.showText3();
return this.showText1();
}
答案 1 :(得分:0)
您要描述的是一组可观察对象,其中每个可观察对象都确定是否应使用下一个可观察对象。
如果可观察变量的值不满足条件,则使用下一个可观察变量的值,直到达到收集结束为止,但是如果可观察变量确实满足条件,则不需要其余的任何一个可观察的。
可观察对象完成时,您需要积累条件。
您想要一些可扩展的东西。允许您异步解决一长串条件,但在不需要其他逻辑时停止。
您可以结合使用high-order observable,reducers和状态对象。
高阶可观察物是发出可观察物的可观察物。例如;
const higherOrder$ = of(of(true));
让我们使用状态对象来保持 satisfy 条件和值的累积。
interface State {
// continue when value is false
satisfy: boolean;
// accumulation of data
values: {[key:string]: any};
}
让我们从默认状态值开始。
const DEFAULT_STATE = {
satisfy: false,
values: {
savedLocally: false,
onServer: false
}
};
让我们定义将产生将累积的值的可观察物。
satisfy
和values
。satisfy
为 false ,就会使用下一个可观察值。values
将累积到最终结果中。const savedLocally$ = this.http.get(...).pipe(map(resp => ({
satisfy: Boolean(resp), values: {savedLocally: resp}
})));
const checkOnServer$ = this.http.get(...).pipe(map(resp => ({
satisfy: Boolean(resp), values: {onServer: resp}
})));
我们可以创建一个高阶可观察值,切换到每个可观察值,累加结果并停止在第一个满足的值上。
在这里,我使用scan()运算符来累加每个发射值上的值。
of(savedLocally$, checkOnServer$).pipe(
switchMap(ob$ => ob$),
scan((acc, next) => ({
satisfy: next.satisfy,
values: {...acc.values, ...next.values}
}), DEFAULT_STATE),
filter(state => state.satisfy),
first(),
map(state => state.values)
).subscribe(values => console.log(values));
现在,我不知道这是否比您现在拥有的更简单,但它确实可以扩展以支持一长串可观察量。
在此示例中,switchMap()
无权访问上一个状态值。可以做到,但是更复杂,我将需要时间考虑如何去做。