我如何简化这个序列,因为我似乎正在重新创造厄运的金字塔,并且应该有更多的Rx-y方式。
public isEligibleForOffers(): Observable<Boolean> {
return Observable.create((observer) => {
this.getAccounts().subscribe(
(accounts) => {
if (!this.accountsAreInCredit(accounts)) {
observer.next(false);
} else {
this.getOffers(accounts).subscribe(
(data: Offers) => {
let isEligible = (data.eligible && this.eligibleForAny(data) === true && this.registeredForAny(data) !== true);
observer.next(isEligible);
}
);
}
});
});
}
我需要进行XHR调用以获取帐户集合,如果帐户有信用,则进行另一次XHR调用以获取当前优惠,如果用户有资格获得任何优惠,则返回true,否则返回false。
基本上
我所询问的内容与我在SO上看到的内容之间的区别有两个:
另一个类似的情况可能是(1)获取一个令牌,然后(2)在后续请求中使用该令牌。
答案 0 :(得分:0)
如果要链接可观察量,请使用switchMap
或flatMap
。此外,您不需要使用Observable.create()
故意创建另一个Observable,因为您的this.getAccounts()
已经返回了一个observable。
这应该更简洁:
public isEligibleForOffers(): Observable<Boolean> {
return this.getAccounts().switchMap(accounts => {
if (this.accountsAreInCredit(accounts)) {
return this.getOffers(accounts)
.map((data: Offers) => {
return (data.eligible && this.eligibleForAny(data) === true && this.registeredForAny(data) !== true);
})
}
//you can be explicit by returning a an Observable of false:
return Obersvable.of(false);
})
}
你可以像这样使用它:
this.isEligibleForOffers()
.subscribe(flag => {
//flag is a boolean
if(flag){
//do something
}else{
//do something else
}
})
答案 1 :(得分:0)
鉴于签名:
getAccounts(): Account[]
accountsAreInCredit(accounts: Account[]): boolean
getOffers(accounts: Account[]): Offers
您可以按如下方式对您的功能进行建模:
public isEligibleForOffers(): Observable<Boolean> {
return this.getAccounts()
.filter(accounts => this.accountsAreInCredit(accounts))
.mergeMap(
accounts => this.getOffers(accounts),
(accounts, offers) => offers.eligible && this.eligibleForAny(offers) && !this.registeredForAny(offers))
)
.concat(Rx.Observable.of(false))
.take(1);
}
因此,如果accountsAreInCredit
产生错误,则流将变为空,然后我们使用.concat
运算符向流附加默认值false
。
mergeMap
(又名flatMap
)需要optional argument resultSelector
,您可以在其中映射输出值,以便将它们映射到isEligibleForOffers
布尔值。
然后最后通过限制函数isEligibleForOffers
可以产生的值的数量,我们阻止自己发出true
(来自mergeMap
)和false
(默认来自concat
)作为排放。