web-dev-qa-db-fra.com

retourne la promesse du magasin après l'envoi de redux thunk

J'essaie d'enchaîner les dépêches avec Redux Thunk

function simple_action(){
  return {type: "SIMPLE_ACTION"}
}

export function async_action(){
  return function(dispatch, getState){
    return dispatch(simple_action).then(()=>{...});
  }
}

Comment puis-je obtenir l'envoi pour retourner une promesse du magasin?

PLUS PRÉCISEMENT:

Je ne comprends probablement pas quelque chose ici, mais dans tous les exemples avec redux-thunk, Ils appellent un événement asynchrone séparé (comme fetch), qui renvoie évidemment un Promise.

Ce que je recherche précisément, c’est lorsque j’envoie une action au magasin: comment s’assurer que le magasin a entièrement traité cette action avant qu’il ne se passe autre chose dans la fonction action_creator() ci-dessus.

Idéalement, j'aimerais que le magasin retourne une sorte de promesse, mais je ne comprends pas comment et où cela se produit?

39
l2silver

Ici, vous avez un exemple sur la façon de répartir et de chaîner une action asynchrone. https://github.com/gaearon/redux-thunk

Le middleware thunk sait comment transformer les actions asynchrones thunk en actions, il vous suffit donc d'avoir votre simple_action () pour devenir un thunk et le middleware thunk fera le travail pour vous. Si le middleware voit une action normale, il l'enverra action comme action normale, mais s'il s'agit d'une fonction asynchrone, votre action asynchrone se transformera en action normale.

Donc, votre simple_action doit être un thunk (un thunk est une fonction qui retourne une fonction.) Comme ceci par exemple:

function makeASandwichWithSecretSauce(forPerson) {
  return function (dispatch) {
    return fetchSecretSauce().then(
      sauce => dispatch(makeASandwich(forPerson, sauce)),
      error => dispatch(apologize('The Sandwich Shop', forPerson, error))
    );
  };
}

Lorsque vous utilisez la fonction makeASandwichWithSecretSauce, vous pouvez utiliser la fonction de répartition

store.dispatch(
  makeASandwichWithSecretSauce('Me')
);

Et même

// It even takes care to return the thunk’s return value
// from the dispatch, so I can chain Promises as long as I return them.

store.dispatch(
  makeASandwichWithSecretSauce('My wife')
).then(() => {
  console.log('Done!');
});

Voici un exemple complet sur la façon dont vous pouvez écrire des créateurs d’action qui envoient des actions et des actions asynchrones à partir d’autres créateurs d’action et créer votre flux de contrôle avec Promises.

function makeSandwichesForEverybody() {
  return function (dispatch, getState) {
    if (!getState().sandwiches.isShopOpen) {
      // You don’t have to return Promises, but it’s a handy convention
      // so the caller can always call .then() on async dispatch result.
      return Promise.resolve();
    }

    //Do this action before starting the next one below 
    dispatch(simple_action());

    // We can dispatch both plain object actions and other thunks,
    // which lets us compose the asynchronous actions in a single flow.
    return dispatch(
      makeASandwichWithSecretSauce('My Grandma')
    ).then(() =>
      Promise.all([
        dispatch(makeASandwichWithSecretSauce('Me')),
        dispatch(makeASandwichWithSecretSauce('My wife'))
      ])
    ).then(() =>
      dispatch(makeASandwichWithSecretSauce('Our kids'))
    ).then(() =>
      dispatch(getState().myMoney > 42 ?
        withdrawMoney(42) :
        apologize('Me', 'The Sandwich Shop')
      )
    );
  };
}
//apologize and withdrawMoney are simple action like this for example
      return {
        type:  "END_SUCESS"
      }

//usage

store.dispatch(
  makeSandwichesForEverybody()
).then(() =>
    console.log("Done !");
);

Pour créer vos propres promesses, vous pouvez utiliser une bibliothèque telle que bluebird.

// EDIT: Pour être sûr que le magasin a entièrement traité cette action avant toute autre action dans la fonction action_creator (), vous pouvez envoyer cette simple_action avant action_creator (); // J'ai ajouté ce commentaire au code //Do this action before starting the next one below

27
Aaleks

dispatch retournera quelle que soit l'action/fonction qu'il appelle retourne; donc si vous souhaitez enchaîner certaines activités (selon votre exemple), votre action devra renvoyer un Promise.

Comme @Aaleks le mentionne, si votre action était un thunk, vous pouvez créer un scénario dans lequel vous renvoyez un Promise, vous pouvez alors faire ce que vous avez mentionné.

BTW je pense nommer votre thunkaction_creator est un peu trompeur, car simple_action est en fait un créateur d’action dans le langage Redux - l’a modifié en conséquence :)

4
a darren

C'est un motif que j'ai utilisé récemment:

export const someThenableThunk = someData => (dispatch, getState) => Promise.resolve().then(() => {
  const { someReducer } = getState();
  return dispatch({
    type: actionTypes.SOME_ACTION_TYPE,
    someData,
  });
});

Lorsque vous dispatch(someThenableThunk('hello-world')), il retourne un objet Promise auquel vous pouvez chaîner d'autres actions.

3
Mapsy