简体   繁体   English

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

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

After a successful login, I am trying to store a token in local storage before fetching a user's config.成功登录后,我尝试在获取用户配置之前将令牌存储在本地存储中。 At the moment I'm just storing the token from within mergeMap before fetching the config in the return statement.目前,我只是在获取 return 语句中的配置之前从mergeMap存储令牌。 However, I'm pretty sure there's a way to use concat or concatMap to call the store and fetch functions in sequence.但是,我很确定有一种方法可以使用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'
      });
    })
  );

Below is one of my attempts which proved unsuccessful.下面是我的尝试之一,但被证明是不成功的。 Although there might be other ways of handling the storing and fetching in this case from within a component, I would like to know how this pattern should work for other cases I have.尽管在这种情况下可能有其他方法可以从组件内部处理存储和获取,但我想知道这种模式应该如何适用于我拥有的其他情况。

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'})
      );
    })
  );

I would go with the first approach you have stated in your question, as localStorage.setItem() is synchronous, thus it will always be called, before FETCH_CONFIG action is returned..我会采用您在问题中陈述的第一种方法,因为localStorage.setItem()是同步的,因此在返回FETCH_CONFIG操作之前,它总是会被调用。

However, if you are looking for alternative approaches, I would suggest you to separate the logic by using the tap() operator before returning the FETCH_CONFIG action.但是,如果您正在寻找替代方法,我建议您在返回FETCH_CONFIG操作之前使用tap()运算符分离逻辑。 This will also ensure that both actions are called in sequence.这也将确保按顺序调用这两个操作。

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

However, if you really want to use concat() , you will need to wrap the localStorage.setItem() action in of() to convert it into an observable, as concat() requires all members to be observables, and it will need to wait for the first subscription( localStorage.setItem() ) to be completed before the second one( FETCH_CONFIG ) can start.但是,如果您真的想使用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'})
      );
    }),
  );

Maybe you can try use last() operator, Concat will emit when each item in the sequence completes itself so that's why it doesn't work.也许您可以尝试使用last()运算符,Concat 会在序列中的每个项目自行完成时发出,这就是它不起作用的原因。

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

concat is used for executing observables in order as previous complete. concat用于按照先前完成的顺序执行可观察对象。

Check doc from learnrx.iolearnrx.io检查文档

You can think of concat like a line at an ATM, the next transaction (subscription) cannot start until the previous completes!你可以把 c​​oncat 想象成 ATM 上的一条线,下一个交易(订阅)在前一个完成之前不能开始!

In your example, I don't think you need any of those operators since you're not doing anything asynchronous in your flow.在您的示例中,我认为您不需要任何这些运算符,因为您没有在流程中执行任何异步操作。

You could simply change your code with the following:您可以简单地使用以下内容更改您的代码:

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.

相关问题 如何在 RxJS/redux-observable 与 redux-saga 中对操作进行排序? - How do I sequence actions in RxJS/redux-observable vs redux-saga? Redux-Observable中具有依赖项的多个动作 - Multiple actions with dependencies in Redux-Observable 如何在 redux-observable 史诗中链接 RxJS observable? - How can I chain RxJS observable in a redux-observable epic? 如何从redux-observable调度多个动作? - How to dispatch multiple actions from redux-observable? 在Redux可观察到的场景中使用史诗对两个动作进行排序 - Sequencing two actions together using an epic in redux-observable 如何在 ngrx/effect (redux-observable) 中分派多个动作? - How to dispatch multiple actions in ngrx/effect (redux-observable)? 使用redux-thunk和redux-observable - use of redux-thunk with redux-observable 在可以通过redux-observable完成一些异步操作之后,如何对redux操作进行排序? - How can I sequence redux actions after some async action completed in redux-observable? 如何从错误处理程序中调度操作并立即在redux-observable中打破其余的Observable链? - How to dispatch actions from an error handler and immediately break the rest of the Observable chain in redux-observable? 使用 redux-thunk / redux-observable 和 redux 的回调 - Callbacks using redux-thunk / redux-observable with redux
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM