RxJS 序列的更好方法
Better way of RxJS Sequence
如何简化这个序列,因为我似乎在重新创建厄运金字塔,应该有更多的 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 电话来获取当前优惠,如果用户有资格获得任何优惠 return真否则假。
基本上
- 进行初始 XHR 调用
- 当你有结果时
- 使用第一次调用的结果进行第二次 XHR 调用
- 当你有结果时
- 做出最终决定。
我问的和我在 SO 上看到的有两个区别:
- 这些异步操作是按顺序且不重叠的
- 第一个响应的有效负载用于第二个
另一个类似的情况可能是 (1) 获取令牌,然后 (2) 在后续请求中使用令牌。
如果要链接可观察对象,请使用 switchMap
或 flatMap
。此外,您不需要使用 Observable.create()
故意创建另一个 Observables,因为您的 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
}
})
给出的签名:
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
产生 false,流将变为空,然后我们使用 .concat
运算符将默认值 false
附加到流。
mergeMap
(又名 flatMap
)接受一个 optional argument resultSelector
,您可以在其中映射输出值,因此我们将它们映射到 isEligibleForOffers
布尔值。
然后最后通过限制函数 isEligibleForOffers
可以产生的值的数量,我们防止我们自己发出 true
(来自 mergeMap
)和 false
(默认来自 concat
) 作为排放量。
如何简化这个序列,因为我似乎在重新创建厄运金字塔,应该有更多的 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 电话来获取当前优惠,如果用户有资格获得任何优惠 return真否则假。
基本上
- 进行初始 XHR 调用
- 当你有结果时
- 使用第一次调用的结果进行第二次 XHR 调用
- 当你有结果时
- 做出最终决定。
我问的和我在 SO 上看到的有两个区别:
- 这些异步操作是按顺序且不重叠的
- 第一个响应的有效负载用于第二个
另一个类似的情况可能是 (1) 获取令牌,然后 (2) 在后续请求中使用令牌。
如果要链接可观察对象,请使用 switchMap
或 flatMap
。此外,您不需要使用 Observable.create()
故意创建另一个 Observables,因为您的 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
}
})
给出的签名:
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
产生 false,流将变为空,然后我们使用 .concat
运算符将默认值 false
附加到流。
mergeMap
(又名 flatMap
)接受一个 optional argument resultSelector
,您可以在其中映射输出值,因此我们将它们映射到 isEligibleForOffers
布尔值。
然后最后通过限制函数 isEligibleForOffers
可以产生的值的数量,我们防止我们自己发出 true
(来自 mergeMap
)和 false
(默认来自 concat
) 作为排放量。