Comment terminer tous les récupérer avant l'exécution de la fonction suivante dans Réagir?
À l'aide de ReactJS, j'ai deux différentes API des points que j'essaie de le faire et de le restructurer: students
et scores
. Ils sont à la fois un tableau d'objets.
Mon objectif est : tout d'abord, les étudiants et les scores, et le second, avec les étudiants et les scores enregistrés dans l'état, je vais les modifier et de créer un nouvel état basé sur les étudiants et les scores de l'état. En bref, j'ai 3 fonctions: getStudents
, getScores
, et rearrangeStudentsAndScores
. getStudents
et getScores
besoin avant la fin de la rearrangeStudentsAndScores
pouvez exécuter.
Mon problème est: parfois rearrangeStudentsAndScores
avant getScores
complète. Que foiré rearrangeStudentsAndScores
. Mais parfois, il serait complète. Je ne sais pas pourquoi il fonctionne à 50% du temps, mais j'en ai besoin pour le faire fonctionner à 100% du temps.
C'est ce que j'ai à fetch
students and scores
dans mon Client
fichier:
function getStudents(cb){
return fetch(`api/students`, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then((response) => response.json())
.then(cb)
};
function getScores(cb){
return fetch(`api/scores`, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then((response) => response.json())
.then(cb)
};
Je puis à les combiner:
function getStudentsAndScores(cbStudent, cbScores, cbStudentsScores){
getStudents(cbStudent).then(getScores(cbScores)).then(cbStudentsScores);
}
Dans mon réagir application, j'ai le texte suivant:
getStudentsAndScores(){
Client.getStudentsAndScores(
(students) => {this.setState({students})},
(scores) => {this.setState({scores})},
this.rearrangeStudentsWithScores
)
}
rearrangeStudentsWithScores(){
console.log('hello rearrange!')
console.log('students:')
console.log(this.state.students);
console.log('scores:');
console.log(this.state.scores); //this returns [] half of the time
if (this.state.students.length > 0){
const studentsScores = {};
const students = this.state.students;
const scores = this.state.scores;
...
}
}
En quelque sorte, par le moment j' rearrangeStudentsWithScores
, this.state.scores
sera toujours []
.
Comment puis-je m'assurer que this.state.students
et this.state.scores
sont tous deux chargés avant que je rearrangeStudentsWithScores
?
OriginalL'auteur Iggy | 2017-07-07
Vous devez vous connecter pour publier un commentaire.
Votre code mélanges poursuite des rappels et de Promesses. Vous trouverez qu'il est plus facile de raisonner sur ce que vous utilisez une approche asynchrone contrôle de flux. Nous allons utiliser des Promesses, parce que
fetch
les utilise.Ainsi que d'être simple, cette approche est plus efficace car elle rend les deux demandes en même temps; votre approche attendu jusqu'à ce que les étudiants ont été récupérées avant de l'extraction de l'scores.
Voir
Promesse.all
sur MDNOriginalL'auteur joews
Je crois que vous avez besoin d'envelopper vos fonctions en flèche des fonctions. Les fonctions sont invoquées que la promesse de la chaîne est rédigé et envoyé à la boucle d'événements. C'est la création d'une race condition.
Je recommande cet article pour le lire en complément:
Nous Avons un Problème avec des Promesses par Nolan Lawson
Et voici un repo j'ai fait qui a un exemple pour chacun des concepts parlé dans l'article.
Juré Craché
OriginalL'auteur illuminatedSpace
Je recommanderais restructuration légèrement - au lieu de la mise à jour de votre état après chaque extraction appel se termine, attendre les deux pour compléter et mettre à jour l'état de tous à la fois. vous pouvez ensuite utiliser la
setState
méthode de rappel pour exécuter la méthode suivante vous désirez.Vous pouvez utiliser une Promesse bibliothèque comme Bluebird attendre pour chercher de multiples demandes pour terminer avant de faire quelque chose d'autre
Promise.all
natif de la ES2015 Promesses.Promise.join
est défini dans bluebird, j'ai importé et mentionnés ci-dessus - que l'on pourrait certainement utiliserPromise.all
ainsi, et envelopper les 2 appels de fonction dans un tableau!Mon point est que vous n'avez pas besoin de toutes les dépendances pour résoudre ce problème 🙂
OriginalL'auteur Anuj