rxjs可观察管道中的建模和if / else模式

时间:2019-03-30 15:29:58

标签: javascript if-statement rxjs rxjs6 redux-observable

我有一个史诗般的地方,我正在听动作流,当发生'AUTH_STATUS_CHECKED'动作时,切换到新的可观察authState(app.auth())。这个新的观察值告诉我是否通过了身份验证。

如果auth observable返回了用户,则以该用户作为有效负载来调度'SIGNED_IN'操作。

如果不存在用户,则放弃承诺app.auth().signInWithPopup(googleAuthProvider),并在得到响应分派'SIGNED_IN'时放弃。

如果有任何错误,请抓住它们并在控制台中通知我。

基于上面的逻辑,我已经实现了下面的管道

export const fetchAuthStatus = action$ =>
      action$.pipe(
        ofType('AUTH_STATUS_CHECKED'),
        switchMap(() =>
          authState(app.auth()).pipe(
            map(user =>
              user
                ? { type: 'SIGNED_IN', payload: user }
                : app
                    .auth()
                    .signInWithPopup(googleAuthProvider)
                    .then(user => ({ type: 'SIGNED_IN', payload: user }))
            ),
            catchError(error => console.log('problems signing in'))
          )
        )
      );

它没有按预期工作。如果没有用户,则将解雇诺言,但它不会等待响应,并且调度也不会被解雇。

我显然是rxjs的新手,但是我很难弄清楚这一点。我浏览了文档,并尝试使用tap()和mergeMap(),但是遇到了相同的错误。

任何指导将不胜感激。

2 个答案:

答案 0 :(得分:1)

如果您需要等到一些内部Observable / Promise完成,则需要用例如包装。 mergeMapconcatMap。由于这两个运算符都要求您返回一个Observable / Promise,因此必须用of()包装该操作,以将一个普通对象变成一个Observable:

import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

...
mergeMap(user => user
  ? of({ type: 'SIGNED_IN', payload: user })
  : app.auth().signInWithPopup(googleAuthProvider)...
)

答案 1 :(得分:1)

但是您的代码可以进行一些优化,建议以更好的方式进行操作,这里您所缺少的是null期望使用普通对象,而map期望使用{{1} }或switchMap对象。

Promise

注意:

  • 不要嵌套管道运算符,尝试尽可能多地使用一根管道
  • 在Rx流之外提取复杂的方法
  • 使用Observable运算符将纯对象转换为Observable