首页 > 解决方案 > 处理多个可观察对象并返回一个值

问题描述

我在下面有一个代码。

loadAll$ = createEffect(() => {
    return this.action$.pipe(
        ofType(LOAD_ALL),
        switchMap(() => {
            
            const localDBCount = from(this.personDBService.countData())
            const localDBList = from(this.personDBService.getAll())
            const serviceList = this.personService.fetchAll();

            forkJoin([localDBCount, localDBList, serviceList]).pipe(
                map(results => {
                    if (results[0] > 0) {
                        //return the list
                        return LOAD_ALL_SUCCESS({ list: results[1] })
                    } else {
                        return LOAD_ALL_SUCCESS({ list: results[2] })
                    }
                })
            )

        }), catchError(err => {
            return of(LOAD_ALL_FAILED({ error: err }))
        })
    )
})

我的目标是在这个效果方法中调用 LOAD_ALL 动作。它将检查 indexDB 中是否存在一些数据或至少 1 个数据,如果存在则返回操作LOAD_ALL_SUCCESS

否则调用其余 api,然后返回操作LOAD_ALL_SUCCESS以及从 api 获取的数据

我在期望返回的 switchMap 上遇到错误,我无法对此提出解决方案。我知道 formJoin 加入了 observables 但不知道如何返回一个值。

personDBService中的所有方法也都返回 Promises,所以我使用from运算符将其转换为 Observable。

错误

'() => void' 类型的参数不能分配给 '(value: TypedAction<"[PERSON] Load All">, index: number) => ObservableInput' 类型的参数。类型“void”不可分配给类型“ObservableInput”。

21             switchMap(() => {

标签: angularrxjsngrx

解决方案


您需要forkJoin在块中返回语句switchMap,因为类型签名switchMap要求您返回一个可观察的

loadAll$ = createEffect(() => {
    return this.action$.pipe(
        ofType(LOAD_ALL),
        switchMap(() => {
            
            const localDBCount = from(this.personDBService.countData())
            const localDBList = from(this.personDBService.getAll())
            const serviceList = this.personService.fetchAll();

            return forkJoin([localDBCount, localDBList, serviceList]).pipe(
                map(results => {
                    if (results[0] > 0) {
                        //return the list
                        return LOAD_ALL_SUCCESS({ list: results[1] })
                    } else {
                        return LOAD_ALL_SUCCESS({ list: results[2] })
                    }
                })
            )

        }), catchError(err => {
            return of(LOAD_ALL_FAILED({ error: err }))
        })
    )
});

或者,一种更清洁的做事方式是删除嵌套管道的使用。这可以通过从 中返回 observable 来完成forkJoin,并通过操作符处理沿主管道返回的相应map操作:

loadAll$ = createEffect(() => {
    return this.action$.pipe(
        ofType(LOAD_ALL),
        switchMap(() => {            
            const localDBCount = from(this.personDBService.countData())
            const localDBList = from(this.personDBService.getAll())
            const serviceList = this.personService.fetchAll();

            return forkJoin([localDBCount, localDBList, serviceList])
        }),
        map((results) => {
          if (results[0] > 0) {
                        //return the list
            return LOAD_ALL_SUCCESS({ list: results[1] })
          } else {
            return LOAD_ALL_SUCCESS({ list: results[2] })
          }
        }),            
    )
})

推荐阅读