我正在尝试创建一种方法来返回可以存储在三个位置之一中的设置。我创建了三个可观察对象,每个可观察对象试图从源中检索设置值。我希望能够以一种创建IF / ELSE IF / ELSE构造的方式“加入”它们,以便只有一个Observable最终发出设置值。从一个可观察的移到另一个可观察的条件是前一个“失败”,即发出的值未通过条件。每个选项的尝试顺序很重要。
到目前为止,我的方法看起来像这样:
getSetting(settingName: string): Observable<any> {
const optionOne$ = this.getItemAtFirst(settingName).pipe(
take(1),
filter(setting => setting && this.isSettingValid(settingName, setting)));
const optionTwo$ = this.getItemAtSecond().pipe(
take(1),
filter(setting => setting && this.isSettingValid(settingName, setting)));
const optionThree$ = of(this.defaultSettingValue);
return merge(optionOne$, optionTwo$, optionThree$);
}
这显然不起作用,因为merge
不能提供我所需的选择效果。
有什么建议吗?预先感谢!
答案 0 :(得分:3)
编辑:TL; DR
将 0.45
0.45
0.45
0.45
0
0
0
0.7
0.7
替换为<embed src="publicMedia/fprefaces/first.pdf#toolbar=0" width="100%" height="100%" oncontextmenu= "return false;" >
,然后将merge
添加到concat
上的管道中:
first
concat
顺序地订阅每个可观察对象,这意味着concat(optionOne$, optionTwo$, optionThree$)
.pipe(
first()
);
首先被订阅,它发出其值,当它完成时,它被取消订阅,然后concat
订阅{{1} },依此类推...直到所有可观察对象完成,然后最终将所有值作为数组发出。添加optionOne$
可以简化此过程,因为它会在发出第一个值之后完成concat。
您真的需要检查concat
内的所有可观察对象是否将完成,否则您可能会遇到其中一个永远不会发出或完成的情况,这将意味着您永远都不会获得值来自optionTwo$
。
-
假设您的first
如果未通过验证,则返回false,然后将concat
和concat
添加到isSettingValid()
中。请参见下面的稍微修改的版本,以及此处的stackblitz。
此article也是有用的。并且我建议使用这个article的gif动画,以解释操作员及其工作方式-当我试图找出类似的东西时,我总是回到它上面。
我认为这回答了您的问题,因为它发出第一个通过验证的值,而忽略其余值。
pipe()
我还建议像我的代码片段一样删除first()
,并将null检查放入验证函数中-如果这样做imo,它只会使过滤器更易于阅读。为了使内容更简洁,您可以考虑将concat()
和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 &&
和一个具有相同结果的谓词函数:
take(1)
答案 1 :(得分:-2)
应该像链接一样实现。即使使用上述代码,即使您从IndexDB中获取数据,您仍将最终调用MangoDB(等待数据)。除了使之复杂之外,我要做的是将呼叫链接起来。但其全部取决于用例。在这种情况下,我想使用 flatMap 运算符将呼叫链接起来会更好。