es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

NgRX – Orden de ejecución del Selector x Effect

Me gustaría hacer una pregunta sobre una cosa.

Imagina que tienes una clase de servicio Effect así:

@Injectable()
export class GeneralEffect implements OnDestroy {

    private state?: IAppState;

    saveState$ = createEffect(() => this.actions$.pipe(
        ofType(
            logoutAction
        ),
        tap((a) => {
            console.log(this.state);
        })
    ), {dispatch: false});

    constructor(
        private actions$: Actions,
        private store: Store<iappstate>,
    ) {
        this.store.select((state) => state).subscribe((s) => {
            this.state = s;
        });
    }
}

Mi pregunta es, ¿se garantiza que dentro del effect logoutAction el estado se actualizará? En otras palabras, sé que el effect se disparará solo después de que todos los reducers hayan terminado (aquí), pero ¿también significa que la suscripción de select del store (en el constructor) se disparará antes que el effect, o puede haber un escenario en el que dentro de la función “tap” aún se encuentre el estado antiguo (antes del reducer logoutAction)?

Sé que una solución es agregar withLatestFrom(this.store.select((state) => state)) en el pipe del effect, pero solo estoy curioso acerca del orden de ejecución de los selectores observables y los effects.

Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Según el código proporcionado, no se garantiza que el estado se actualice dentro del efecto “logoutAction” antes de que se ejecute la función “tap”. La suscripción “store.select” en el constructor se disparará una vez cuando se instancie el servicio “GeneralEffect”, pero es posible que no refleje los cambios realizados por el efecto “logoutAction”.

    Para asegurarse de que la función “tap” vea el estado actualizado, puede usar el operador “withLatestFrom” para combinar la acción “logoutAction” con el último estado del almacén, de la siguiente manera:

    saveState$ = createEffect(() => this.actions$.pipe(
        ofType(logoutAction),
        withLatestFrom(this.store.select((state) => state)),
        tap(([action, state]) => {
            console.log(state);
        })
    ), {dispatch: false});
    

    De esta manera, la función “tap” siempre verá el último estado del almacén, incluso si fue actualizado por el efecto “logoutAction”.

Comments are closed.