RxJS:ES6 Array every() 等效于检查 Observable 布尔值数组中的每个项目
RxJS: ES6 Array every() equivalent to check each item in an array of Observable booleans
我有一个 'roles' 数组,需要检查用户是否具有这些角色中的每一个。检查这个的函数,return是一个 Observable:
let roles: string[] = ['role1', 'role2']
public userHasRole(role: string): Observable<boolean> {<already implemented>}
我需要 return 一个 Observable<boolean>
或 Promise<boolean>
来指示用户是否拥有每个角色。
我可以用 Promises 解决这个问题:
let promises: Promise<boolean>[] = roles.map(r => this.auth.currentUserHasRole(r).toPromise());
return Promise.all(promises).then(results => results.every(x => x));
但我假设 RxJS 有更优雅的解决方案?我正在使用 rxjs 6.5.
对于 RxJS 方式,尝试:
import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
public userHasRoles(roles: string[]): Observable<boolean> {
return combineLatest(
// spread the array of observables as a comma list
...roles.map(role => this.auth.currentUserHasRole(role)),
).pipe(
map(results => results.every(result => result)),
);
}
根据您的方法签名,您只将一个字符串作为参数,因此您可以简单地使用 findIndex
和 of
运算符将其转换为 Observable
public userHasRole(role:string): Observable<boolean>{
roles.findIndex(i=>i===role)!==-1 ? of(true) : of(false)
}
添加导入语句
import { of } from 'rxjs';
试试这个:
public userHasRoles(roles: string[]): Observable<boolean> {
return from(roles).pipe(
mergeMap((role) => this.auth.currentUserHasRole(role)),
reduce((hasPrevRoles, hasRole) => hasPrevRoles && hasRole),
);
}
使用以下导入:
import { from } from 'rxjs';
import { mergeMap, reduce } from 'rxjs/operators';
from
function first creates an observable that emits the roles in sequence. Then mergeMap
creates a flattened stream of boolean results from calling currentUserHasRole
for each role emitted. Finally reduce
将所有布尔值合并为一个布尔值,该布尔值仅在所有输入布尔值都为真时才为真,类似于 Array.reduce 的工作方式。
reduce
这里类似于 forkJoin:它 returns 一个可观察对象,一旦输入可观察对象完成,它就会发出一次合并值。返回的可观察对象将自行完成。
我有一个 'roles' 数组,需要检查用户是否具有这些角色中的每一个。检查这个的函数,return是一个 Observable:
let roles: string[] = ['role1', 'role2']
public userHasRole(role: string): Observable<boolean> {<already implemented>}
我需要 return 一个 Observable<boolean>
或 Promise<boolean>
来指示用户是否拥有每个角色。
我可以用 Promises 解决这个问题:
let promises: Promise<boolean>[] = roles.map(r => this.auth.currentUserHasRole(r).toPromise());
return Promise.all(promises).then(results => results.every(x => x));
但我假设 RxJS 有更优雅的解决方案?我正在使用 rxjs 6.5.
对于 RxJS 方式,尝试:
import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
public userHasRoles(roles: string[]): Observable<boolean> {
return combineLatest(
// spread the array of observables as a comma list
...roles.map(role => this.auth.currentUserHasRole(role)),
).pipe(
map(results => results.every(result => result)),
);
}
根据您的方法签名,您只将一个字符串作为参数,因此您可以简单地使用 findIndex
和 of
运算符将其转换为 Observable
public userHasRole(role:string): Observable<boolean>{
roles.findIndex(i=>i===role)!==-1 ? of(true) : of(false)
}
添加导入语句
import { of } from 'rxjs';
试试这个:
public userHasRoles(roles: string[]): Observable<boolean> {
return from(roles).pipe(
mergeMap((role) => this.auth.currentUserHasRole(role)),
reduce((hasPrevRoles, hasRole) => hasPrevRoles && hasRole),
);
}
使用以下导入:
import { from } from 'rxjs';
import { mergeMap, reduce } from 'rxjs/operators';
from
function first creates an observable that emits the roles in sequence. Then mergeMap
creates a flattened stream of boolean results from calling currentUserHasRole
for each role emitted. Finally reduce
将所有布尔值合并为一个布尔值,该布尔值仅在所有输入布尔值都为真时才为真,类似于 Array.reduce 的工作方式。
reduce
这里类似于 forkJoin:它 returns 一个可观察对象,一旦输入可观察对象完成,它就会发出一次合并值。返回的可观察对象将自行完成。