ngrx Effects: Are actions dispatched by one effect processed immediately by other effects?

十年热恋 提交于 2019-12-05 11:30:25

To answer your concluding questions:

  • Am I doing something wrong?
  • No, I don't reckon you are doing anything wrong.
  • Is it incorrect to expect that actions are processed by the reducers in the same order that they are dispatched?
  • That order would seem logical but apparently you can't expect that at the moment

There seems to be a bug causing this behaviour. You are most probably experiencing it since you are directly mapping to another action. Usually, if you have an asynchronous operation or something like that, the reducer has time to finish before the effect listening to the next action starts.

Perhaps not a part of your question, but a solution to your specified problem would be to navigate to your new route directly in SUCCESS with the help of your payload, or pass the payload to ADVANCE.

Links below are reported issues in effects-, store- and rxjs-projects that are related to yours:

Seems like they're working on it :)

It might work to replace your .map in the catch of the START action with a .concatMap and put both your map to SUCCESS and to ACTION there.

@Effect() start$ = this.actions$
    .ofType('START')
    .map(toPayload)
    .switchMap(input => doAsyncTask(input)
        .concatMap(result => {
            return Observable.from([type: 'SUCCESS', payload: result,
                                    type: 'ADVANCE'])
        .catch(error => ({type: 'ERROR', payload: error})));

The purpose of ngex/effects is to act as the middle-ware in a redux based environment.

So what you are basically doing here is calling the 'success' action that should work on both reducer and continue to another action is the middle-ware. But that's the consonant of effecs, It should intercept actions and handle them by itself, Only after is async handling it dispatch action.

So what is happening here? you dispatch success to two different places, one should handle by the reducer and one by the middle-ware. I'm not sure if it always like that but middle-wares will intercept incoming action before it hits the reducer. I think that if you'll modify you code a little bit it should work. Try to do something like :

@Effect() start$ = this.actions$
    .ofType('START')
    .map(toPayload)
    .switchMap(input => doAsyncTask(input)
        .map(result =>{
               this.store$.dispatch(
               {type: 'SUCCESS',
                payload: result
                });
               this.store$.dispatch(
               {type: 'ADVANCE'})

}

        .catch(error => ({type: 'ERROR', payload: error})));

You see what I'm doing here? I've removed the middle-ware that intercept 'success', So not the 'success' hits the reducer. Right after it it dispatch another action of type 'advance' that should hit your middle-ware after the 'success' is done been handling.

Hope it help's.

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