相互映射可观察对象的最佳方法

时间:2018-08-14 02:41:20

标签: angular rxjs

我正在Angular项目中工作,我有一个Observable AA从HTTP请求中发出一个值,我想根据用户角色(管理员,超级用户和用户)使用另一个Observable过滤该值。我使用switchMap和if / else解决了问题,但我认为有更好的方法。我的解决方案是:

getObervableA.pipe(
    switchMap(itens => {
        function filterItens(allowedItens) {
            return itens.filter(item => {
                return allowedItens.some(({id}) => id === item.id);
            });
        }

        if (isAdmin) {
            return of(itens);
        } else if (isSuperuser) {
            getSuperuserAllowedItens.pipe(map(allowedItens => filterItens(allowedItens)));
        } else {
            getUserAllowedItens.pipe(map(allowedItens => filterItens(allowedItens)));
        }
    }),
).subscribe(
    // do something with A filtered
)

我怀疑我可以在switchMap内通过if / else ...

谢谢!

2 个答案:

答案 0 :(得分:2)

最好使用这些用例类型的可观察值,而不是使用if / else。 它具有更好的可读性并且更易于测试

如果您不需要switchMap,我们可以使用filtermerge做一个更简单的方法,就像这样:

 function filterItens(allowedItens, itens) {
      return itens.filter(item => {
        return allowedItens.some(({ id }) => id === item.id);
      });
    }

   admin$ = source.pipe(filter(() => isAdmin));
   superUser$ = source.pipe(filter(() => isSuperUser), mergeMap((itens) => getSuperuserAllowedItens.pipe(map(allowedItens => filterItens(allowedItens, itens))))
   user$ = source.pipe(filter(() => !isAdmin && !isSuperUser), mergeMap((itens) => getUserAllowedItens.pipe(map(allowedItens => filterItens(allowedItens, itens))))
   getObervableA.pipe(merge(admin$, superUser$, user$)).subscribe()

答案 1 :(得分:1)

有多种方法,具体取决于您的情况。您的解决方案已经正确。但是,如果您的Observables彼此独立,则forkJoin会非常有用,并且性能会更高:

forkJoin(getObservableA, getSuperuserAllowedItens, getUserAllowedItens)
    .pipe(map(([itens, superuserItens, userItens]) => {

        if (isAdmin) {
            return itens;
        }

        if (isSuperUser) {
            return itens.filter(item => superuserItens.some(({id}) => id === item.id));
        }

        return itens.filter(item => userItens.some(({id}) => id === item.id));
    }))

这里是(几乎)三元运算符的一个衬里:

forkJoin(getObservableA, getSuperuserAllowedItens, getUserAllowedItens)
    .pipe(map(([itens, superuserItens, userItens]) => {
        return isAdmin ? itens :
            isSuperUser ? itens.filter(item => superuserItens.some(({id}) => id === item.id)) :
                itens.filter(item => userItens.some(({id}) => id === item.id))
    }))

此外,如果您的条件是互斥的,也就是,管理员不能是超级用户,超级用户也不能是普通用户(或者,一个人只能有一个角色),那么代码就会失效简单:

forkJoin(getObservableA, getSuperuserAllowedItens, getUserAllowedItens)
    .pipe(map(([itens, superuserItens, userItens]) => {
        return itens.filter(item => {
            return isAdmin || superuserItens.some(({id}) => id === item.id) || userItens.some(({id}) => id === item.id)
        })
    }))