redux-observable return multiple action types

丶灬走出姿态 提交于 2020-02-08 09:47:11

问题


I am using redux-observable and this is what I am trying to do.

  1. When an actiontype of 'APPLY_SHOPPING_LIST' comes in dispatch 'APPLYING_SHOPPING_LIST' and after 5 seconds dispatch 'APPLIED_SHOPPING_LIST'. This is the code that I have come up with so far

    const applyingShoppingListSource = action$.ofType('APPLY_SHOPPING_LISTS').mapTo({ type: 'APPLYING_SHOPPING_LISTS' });
    
    const applyingShoppingListSourceOther = action$.ofType('APPLY_SHOPPING_LISTS').mapTo({ type: 'APPLIED_SHOPPING_LISTS' }).delay(5000);
    
    const concatList = applyingShoppingListSource.concat(applyingShoppingListSourceOther);
    

    return concatList;

Now the problem is that only 'APPLYING_SHOPPING_LISTS' gets fired, the 'APPLIED_SHOPPING_LISTS' does not get fired to the reducer at all. Am I missing something here?

Just to add to this, when I used flatMap it worked, given below is the code

 return action$.ofType('APPLY_SHOPPING_LISTS')
        .flatMap(() => Observable.concat(Observable.of({ type: 'APPLYING_SHOPPING_LISTS' }), Observable.of({ type: 'APPLYING_SHOPPING_LISTS' });

I am confused how this works and the other does not?


回答1:


There's a couple issues. Since Observables are lazy, your second action$.ofType('APPLY_SHOPPING_LISTS') for applyingShoppingListSourceOther is being concat'd after the first applyingShoppingListSource, so it won't be listening for APPLY_SHOPPING_LISTS until after the first one is has completed, but it will never realistically complete because you're taking all actions that match, forever.

Said another way, your code does this:

  • Start listening for APPLY_SHOPPING_LISTS and when received map it to APPLYING_SHOPPING_LISTS
  • When that first Observable completes (it never does) start listening for APPLY_SHOPPING_LISTS again, this time when received map it to APPLIED_SHOPPING_LISTS but wait 5000 ms before emitting it.

You could solve the particular issue of the first not ever completing by using .take(1) or .first() (same thing), but you usually need to write your epics to not ever stop listening so they respond to actions at any time.

I think what you want is this:

const exampleEpic = action$ =>
  action$.ofType('APPLY_SHOPPING_LISTS')
    .mergeMap(() =>
      Observable.of({ type: 'APPLYING_SHOPPING_LISTS' })
        .concat(
          Observable.of({ type: 'APPLIED_SHOPPING_LISTS' })
            .delay(5000)
        )
    );

I used mergeMap but you may want to use switchMap to cancel any previously pending APPLIED_SHOPPING_LISTS that haven't emitted yet. Your call.



来源:https://stackoverflow.com/questions/43748453/redux-observable-return-multiple-action-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!