繁体   English   中英

有没有办法在 RxJS / Redux-observable 中连接非 Redux 操作?

[英]Is there a way to concat non-Redux actions in RxJS / Redux-observable?

成功登录后,我尝试在获取用户配置之前将令牌存储在本地存储中。 目前,我只是在获取 return 语句中的配置之前从mergeMap存储令牌。 但是,我很确定有一种方法可以使用concatconcatMap调用 store 和 fetch 函数。

const authEpic = action$ =>
  action$.pipe(
    ofType('auth/AUTHENTICATION_SUCCESS'),
    mergeMap(action => {
      const { jwt } = action.payload;

      localStorage.setItem('token', jwt);

      return of({
        type: 'user/FETCH_CONFIG'
      });
    })
  );

下面是我的尝试之一,但被证明是不成功的。 尽管在这种情况下可能有其他方法可以从组件内部处理存储和获取,但我想知道这种模式应该如何适用于我拥有的其他情况。

const authEpic = action$ =>
  action$.pipe(
    ofType('auth/AUTHENTICATION_SUCCESS'),
    mergeMap(action => {
      const { jwt } = action.payload;

      return concat(
        localStorage.setItem('token', jwt),
        of({ type: 'user/FETCH_CONFIG'})
      );
    })
  );

我会采用您在问题中陈述的第一种方法,因为localStorage.setItem()是同步的,因此在返回FETCH_CONFIG操作之前,它总是会被调用。

但是,如果您正在寻找替代方法,我建议您在返回FETCH_CONFIG操作之前使用tap()运算符分离逻辑。 这也将确保按顺序调用这两个操作。

const authEpic = action$ =>
  action$.pipe(
    ofType('auth/AUTHENTICATION_SUCCESS'),
    tap(({ payload: { jwt } }) => {
      localStorage.setItem('token', jwt);
    }),
    mergeMap((action) => (of({
      type: 'user/FETCH_CONFIG'
    }))
  );

但是,如果您真的想使用concat() ,则需要将localStorage.setItem()操作包装在of()以将其转换为可观察对象,因为concat()要求所有成员都是可观察对象,并且需要在第二个订阅( FETCH_CONFIG )可以开始之前等待第一个订阅( localStorage.setItem() )完成。

const authEpic = action$ =>
  action$.pipe(
    ofType('auth/AUTHENTICATION_SUCCESS'),
    mergeMap(action => {
      const { jwt } = action.payload;

      return concat(
        of(localStorage.setItem('token', jwt)),
        of({ type: 'user/FETCH_CONFIG'})
      );
    }),
  );

也许您可以尝试使用last()运算符,Concat 会在序列中的每个项目自行完成时发出,这就是它不起作用的原因。

  reuturn concat(
    of(localStorage.setItem('token', jwt)),
    of({ type: 'user/FETCH_CONFIG'})
  ).pipe(last());

concat用于按照先前完成的顺序执行可观察对象。

learnrx.io检查文档

你可以把 c​​oncat 想象成 ATM 上的一条线,下一个交易(订阅)在前一个完成之前不能开始!

在您的示例中,我认为您不需要任何这些运算符,因为您没有在流程中执行任何异步操作。

您可以简单地使用以下内容更改您的代码:

action$.pipe(
  ofType('auth/AUTHENTICATION_SUCCESS'),
  tap(action => localStorage.setItem('token', action.payload)),
  mapTo({ type: 'user/FETCH_CONFIG'})
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM