1
votes

Comment définirState après une boucle de fonctions asynchrones

La réponse la plus proche que j'ai pu trouver était celle-ci, qui n'a pas aidé puisque j'ai besoin de setState: Comment exécuter une fonction après avoir utilisé array.map?

Je pense que la réponse devrait être simple, mais je suis assez novice en Javascript. J'essaye de déplacer le setState pour isLoading vers APRÈS avoir extrait tous les profils.

componentDidMount() {
    console.log('MatchesScreen init props: ', Object.keys(this.props))

    Object.keys(this.props.profile.profile.matches).map((username) => {
      console.log('match', username)
      url = 'https://xxxxxxx.execute-api.us-west-2.amazonaws.com/prod/profile?username=' + username
      fetch(url, {
        method: 'GET',
      })
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          isLoading: false,
        })
        this.props.addMatch(responseJson)
      })
      .catch((error) =>{
        console.error(error);
      })
    })
  }

J'ai essayé diverses choses comme ajouter un .then () à la fonction de carte, mais jusqu'à présent pas de chance.


0 commentaires

3 Réponses :


0
votes

Essayez d'utiliser le modèle async / wait comme suit:

async componentDidMount() {
...
    Object.keys(this.props.profile.profile.matches).map((username) => {
    ...
      await fetch(url, {
      ...

puis déplacez votre méthode setState dans son propre callback, que vous pouvez appeler dans vos instructions .then () après votre fetch.

J'aime cette référence: https://alligator.io/js/async-functions/


0 commentaires

2
votes

Vous pouvez renvoyer chaque promesse dans la fonction .map () , ce qui vous laisserait avec un tableau de promesses. Une fois que vous avez cela, vous pouvez utiliser Promise.all () pour attendre que toutes les promesses du tableau se résolvent.

componentDidMount() {
    console.log('MatchesScreen init props: ', Object.keys(this.props))

    // Put all promises into an array
    const promisesArray = Object.keys(this.props.profile.profile.matches).map((username) => {
        console.log('match', username)
        url = 'https://xxxxxxx.execute-api.us-west-2.amazonaws.com/prod/profile?username=' + username;
        // Return each promise
        return fetch(url, {
                method: 'GET',
            })
            .then((response) => response.json())
            .then((responseJson) => {
                this.props.addMatch(responseJson)
            })
            .catch((error) =>{
                console.error(error);
            });
    });

    // Wait for all promises in array to resolve
    Promise.all(promisesArray)
        .then(() => {
            // This will execute once all promises have resolved
            this.setState({
                isLoading: false,
            });
        })
        .catch(e => console.error(e));
}


0 commentaires

0
votes

Essayez d'encapsuler Object.keys () dans une boucle while avec une instruction if à la fin.

var profilesMatched = 0;
while(profilesMatched < Object.keys(this.props.profile.profile.matches).length){
    Object.keys(this.props.profile.profile.matches).map((username) => {
      console.log('match', username)
      url = 'https://xxxxxxx.execute-api.us-west-2.amazonaws.com/prod/profile?username=' + username
      fetch(url, { method: 'GET', })
      .then((response) => {response.json()})
      .then((responseJson) => {
        this.props.addMatch(responseJson);
        profilesMatched++;
      })
      .catch((error) => {
        console.error(error);
      });
    });
    if(profilesMatched == Object.keys(this.props.profile.profile.matches).length){
        this.setState({
          isLoading: false,
        })
    }
}


0 commentaires