RxJs 管道图和 if 条件再次发出一个请求
RxJs pipe map and if condition make one request again
我想在angular中实现一个布尔返回方法。我是这样写的
isViewEnabled(id: string): Observable<boolean> {
const isAppEnabledObs = this.serviceAccessor.isAppEnabled(id, appName);
const configObs = this.getConfigFromServer(id);
const isItSharedObs = this.selectionService.getSharingStatus(id);
return forkJoin([isAppEnabledObs, configObs, isItSharedObs]).pipe(
map(results => {
const isAppEnabled = results[0];
const config = results[1];
const isItShared = results[2];
const isToggleEnabled= config ? config.isToggleEnabled: false;
return !isItShared ? isToggleEnabled : isToggleEnabled && isAppEnabled;
})
);
}
现在我可以调用 forkJoin
中的所有请求,并且所有请求都会立即解决。通常在我们的应用程序中,大多数时候 isItShared
变量是 false
。在此逻辑中,isAppEnabled
变量仅当且仅当 isItShared
变量为 true
.
时才能更改条件
我的问题是如何实现此方法,以便仅在 isItShared
变量的计算结果为 true
时才发出 this.serviceAccessor.isAppEnabled(id, appName);
请求。因为大多数时候我不想调用 this.serviceAccessor.isAppEnabled(id, appName);
方法,因为在大多数情况下它会降低应用程序的速度。如果 isItShared
是 true
,我想加倍努力
一种方法是按照您现在的方式在 forkJoin
中执行所有其他检查,但将昂贵的操作移至 iif
(docs) 分支.然后检查您的 !isItShared
条件,仅在需要时切换到 isAppEnabled
。
您可以将 isAppEnabledObs
排除在 forkJoin
之外,并使用 switchMap
到 return 仅在必要时才进行 isAppEnabledObs
调用的可观察对象。
isViewEnabled(id: string): Observable<boolean> {
const isAppEnabledObs = this.serviceAccessor.isAppEnabled(id, appName);
const configObs = this.getConfigFromServer(id);
const isItSharedObs = this.selectionService.getSharingStatus(id);
return forkJoin([configObs, isItSharedObs]).pipe(
switchMap(([config, isItShared])=> {
const isToggleEnabled = config ? config.isToggleEnabled: false;
return !isItShared
? of(isToggleEnabled)
: isAppEnabledObs.pipe(
map(isAppEnabled => isToggleEnabled && isAppEnabled)
);
})
);
}
在switchMap
里面,我们需要return一个observable,所以在不需要make的情况下,我们使用of
从isToggleEnabled
创建observable额外的电话。
当需要调用时,我们只需 return 一个将 isAppEnabledObs
响应映射到所需布尔值的可观察对象。
惯用的解决方案
首先调用您需要的服务,执行一些转换,然后使用其输出调用更多服务。这通常分为多个可观察对象,但可以很容易地作为一个单元完成。
本质上:只有在发现isItShared
为真后才调用this.selectionService.getSharingStatus
。
您会看到现在有 3 个操作(forkJoin
-> map
-> switchMap
)在工作,而不是两个。当然,map
和 switchMap
总是可以结合使用,但我建议不要这样做。
随着代码库的增长,将数据转换与订阅逻辑分开可以使您的代码更加简洁(并且更易于重构)。
isViewEnabled(id: string): Observable<boolean> {
return forkJoin({
config: this.getConfigFromServer(id),
isItShared: this.selectionService.getSharingStatus(id)
}).pipe(
map(({config, ...rest}) => ({
isToggleEnabled: config?.isToggleEnabled || false,
...rest
})),
switchMap(({isToggleEnabled, isItShared}) =>
!isItShared ?
of(isToggleEnabled) :
this.selectionService.getSharingStatus(id).pipe(
map(isAppEnabled => isToggleEnabled && isAppEnabled)
)
)
);
}
我想在angular中实现一个布尔返回方法。我是这样写的
isViewEnabled(id: string): Observable<boolean> {
const isAppEnabledObs = this.serviceAccessor.isAppEnabled(id, appName);
const configObs = this.getConfigFromServer(id);
const isItSharedObs = this.selectionService.getSharingStatus(id);
return forkJoin([isAppEnabledObs, configObs, isItSharedObs]).pipe(
map(results => {
const isAppEnabled = results[0];
const config = results[1];
const isItShared = results[2];
const isToggleEnabled= config ? config.isToggleEnabled: false;
return !isItShared ? isToggleEnabled : isToggleEnabled && isAppEnabled;
})
);
}
现在我可以调用 forkJoin
中的所有请求,并且所有请求都会立即解决。通常在我们的应用程序中,大多数时候 isItShared
变量是 false
。在此逻辑中,isAppEnabled
变量仅当且仅当 isItShared
变量为 true
.
我的问题是如何实现此方法,以便仅在 isItShared
变量的计算结果为 true
时才发出 this.serviceAccessor.isAppEnabled(id, appName);
请求。因为大多数时候我不想调用 this.serviceAccessor.isAppEnabled(id, appName);
方法,因为在大多数情况下它会降低应用程序的速度。如果 isItShared
是 true
一种方法是按照您现在的方式在 forkJoin
中执行所有其他检查,但将昂贵的操作移至 iif
(docs) 分支.然后检查您的 !isItShared
条件,仅在需要时切换到 isAppEnabled
。
您可以将 isAppEnabledObs
排除在 forkJoin
之外,并使用 switchMap
到 return 仅在必要时才进行 isAppEnabledObs
调用的可观察对象。
isViewEnabled(id: string): Observable<boolean> {
const isAppEnabledObs = this.serviceAccessor.isAppEnabled(id, appName);
const configObs = this.getConfigFromServer(id);
const isItSharedObs = this.selectionService.getSharingStatus(id);
return forkJoin([configObs, isItSharedObs]).pipe(
switchMap(([config, isItShared])=> {
const isToggleEnabled = config ? config.isToggleEnabled: false;
return !isItShared
? of(isToggleEnabled)
: isAppEnabledObs.pipe(
map(isAppEnabled => isToggleEnabled && isAppEnabled)
);
})
);
}
在switchMap
里面,我们需要return一个observable,所以在不需要make的情况下,我们使用of
从isToggleEnabled
创建observable额外的电话。
当需要调用时,我们只需 return 一个将 isAppEnabledObs
响应映射到所需布尔值的可观察对象。
惯用的解决方案
首先调用您需要的服务,执行一些转换,然后使用其输出调用更多服务。这通常分为多个可观察对象,但可以很容易地作为一个单元完成。
本质上:只有在发现isItShared
为真后才调用this.selectionService.getSharingStatus
。
您会看到现在有 3 个操作(forkJoin
-> map
-> switchMap
)在工作,而不是两个。当然,map
和 switchMap
总是可以结合使用,但我建议不要这样做。
随着代码库的增长,将数据转换与订阅逻辑分开可以使您的代码更加简洁(并且更易于重构)。
isViewEnabled(id: string): Observable<boolean> {
return forkJoin({
config: this.getConfigFromServer(id),
isItShared: this.selectionService.getSharingStatus(id)
}).pipe(
map(({config, ...rest}) => ({
isToggleEnabled: config?.isToggleEnabled || false,
...rest
})),
switchMap(({isToggleEnabled, isItShared}) =>
!isItShared ?
of(isToggleEnabled) :
this.selectionService.getSharingStatus(id).pipe(
map(isAppEnabled => isToggleEnabled && isAppEnabled)
)
)
);
}