2017-09-08 2 views
1

J'utilise redux-observable avec redux pour les actions asynchrones. À l'intérieur de l'opérateur map de l'epic je fais un pré-traitement car c'est l'endroit central.Redux observable annule l'exécution de l'opérateur suivant?

Mon application appelant la même action à partir de plusieurs composants de conteneur avec des valeurs différentes.

Donc, fondamentalement, je dois annuler ma demande ajax/prochaine exécution de l'opérateur si deepEqual(oldAtts, newAtts) est true

Code -

export default function getProducts(action$, store) { 
    return action$.ofType(FETCH_PRODUCTS_REQUEST) 
    .debounceTime(500) 
    .map(function(action) { 

     let oldAtts = store.getState().catalog.filterAtts 
     let newAtts = Object.assign({}, oldAtts, action.atts) 

     if (deepEqual(oldAtts, newAtts)) { 
     // Don't do new ajax request 
     } 

     const searchString = queryString.stringify(newAtts, { 
     arrayFormat: 'bracket' 
     }) 

     // Push new state 
     pushState(newAtts) 

     // Return new `action` object with new key `searchString` to call API 
     return Object.assign({}, action, { 
     searchString 
     }) 

    }) 
    .mergeMap(action => 
     ajax.get(`/products?${action.searchString}`) 
     .map(response => doFetchProductsFulfilled(response)) 
     .catch(error => Observable.of({ 
     type: FETCH_PRODUCTS_FAILURE, 
     payload: error.xhr.response, 
     error: true 
     })) 
     .takeUntil(action$.ofType(FETCH_PRODUCTS_CANCEL)) 
    ); 
} 

Pas sûr que son chemin droit de le faire à partir épique. Merci d'avance.

+0

Ce n'est pas clair à 100%. Voulez-vous annuler une requête ajax en attente si et seulement si la nouvelle requête est identique? Si ce n'est pas égal, alors vous faites la nouvelle demande en même temps que la précédente? – jayphelps

+0

@jayphelps Je ne veux pas faire de nouvelle requête si les paramètres de requête précédents sont les mêmes que les nouveaux params. –

+0

Désolé, c'est un oui à ma question? – jayphelps

Répondre

2

Vous pouvez le faire:

export default function getProducts(action$, store) { 
    return action$.ofType(FETCH_PRODUCTS_REQUEST) 
    .debounceTime(500) 
    .map(action => ({ 
     oldAtts: store.getState().catalog.filterAtts, 
     newAtts: Object.assign({}, oldAtts, action.atts) 
    })) 
    .filter(({ oldAtts, newAtts }) => !deepEqual(oldAtts, newAtts)) 
    .do(({ newAtts }) => pushState(newAtts)) 
    .map(({ newAtts }) => queryString.stringify(newAtts, { 
     arrayFormat: 'bracket' 
    })) 
    .mergeMap(searchString => ...); 
} 

Mais le plus probable que vous n'avez pas besoin de sauver les atts à l'autre pour faire la comparaison:

export default function getProducts(action$, store) { 
    return action$.ofType(FETCH_PRODUCTS_REQUEST) 
    .debounceTime(500) 
    .map(action => action.atts) 
    .distinctUntilChanged(deepEqual) 
    .map(atts => queryString.stringify(atts, { arrayFormat: 'bracket' })) 
    .mergeMap(searchString => ...); 
} 
+0

Merci @dkl c'est pour moi! –