How to complete all selections before performing the next function in React?

Using ReactJS, I have two different API points that I am trying to get and restructure: studentsand scores. They are an array of objects.

My goal : firstly, to get students and grades, and secondly, with students and grades saved in the state, I will change them and create a new state based on students and grades. In short, I have 3 functions: getStudents, getScoresand rearrangeStudentsAndScores. getStudentsand getScoresmust be completed before rearrangeStudentsAndScores.

My problem : sometimes it rearrangeStudentsAndScoresstarts until completion getScores. It messed rearrangeStudentsAndScoresup. But sometimes it ends. Not sure why it works in 50% of cases, but I need to get it to work in 100% of cases.

This is what I should fetch students and scoresin the file Client:

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)
};

Then I combined them:

function getStudentsAndScores(cbStudent, cbScores, cbStudentsScores){
  getStudents(cbStudent).then(getScores(cbScores)).then(cbStudentsScores);
}

In my interaction application, I have the following:

  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;
    ...

Be that as it may, by the time I get to rearrangeStudentsWithScores, it this.state.scoreswill be the same [].

How can I guarantee that this.state.studentsu this.state.scoresload before launch rearrangeStudentsWithScores?

+4
source share
3 answers

Promises. , . Promises, fetch .

// Refactor getStudents and getScores to return  Promise for their response bodies
function getStudents(){
  return fetch(`api/students`, {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }).then((response) => response.json())
};

function getScores(){
  return fetch(`api/scores`, {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }).then((response) => response.json())
};

// Request both students and scores in parallel and return a Promise for both values.
// `Promise.all` returns a new Promise that resolves when all of its arguments resolve.
function getStudentsAndScores(){
  return Promise.all([getStudents(), getScores()])
}

// When this Promise resolves, both values will be available.
getStudentsAndScores()
  .then(([students, scores]) => {
    // both have loaded!
    console.log(students, scores);
  })

, , ; , , .

. Promise.all MDN

+11

- . setState , , .

Promise, ​​ Bluebird, , -

import Promise from 'bluebird'

getStudents = () => {
  return fetch(`api/students`, {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }).then(response => response.json());
};

getScores = () => {
  return fetch(`api/scores`, {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }).then(response => response.json());
};

Promise.join(getStudents(), getScores(), (students, scores) => {
    this.setState({
        students,
        scores
    }, this.rearrangeStudentsWithScores);
});
0

, . , . .

    function getStudentsAndScores(cbStudent, cbScores, cbStudentsScores){
  getStudents(cbStudent).then(() => getScores(cbScores)).then(cbStudentsScores);
}

: Promises

, , , . Pinky Swear

0

Source: https://habr.com/ru/post/1680994/


All Articles