小编典典

在React中执行下一个功能之前如何完成所有提取?

reactjs

使用ReactJS,我尝试获得两个不同的API点并进行重组:studentsscores。它们都是对象的数组。

我的目标是
:首先,获取学生和分数,然后,将学生和分数保存在状态中,我将对其进行修改,并基于学生和分数状态创建一个新状态。总之,我有3个功能:getStudentsgetScores,和rearrangeStudentsAndScoresgetStudents并且getScores需要完成后rearrangeStudentsAndScores才能运行。

我的问题是
:有时rearrangeStudentsAndScores会在getScores完成之前运行。搞砸rearrangeStudentsAndScores
但是有时它会完成。不知道为什么它会在50%的时间内工作,但是我需要使其在100%的时间内工作。

这是我必须fetch students and scoresClient文件中执行的操作:

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

然后,我将它们组合在一起:

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

在我的react应用程序中,我有以下内容:

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

不知何故,到我到达的时候rearrangeStudentsWithScoresthis.state.scores仍然会[]

在运行之前,如何确保this.state.studentsthis.state.scores都已加载rearrangeStudentsWithScores


阅读 267

收藏
2020-07-22

共1个答案

小编典典

您的代码混合了继续回调和Promises。您会发现使用一种异步流控制方法更容易对此进行推理。让我们使用Promises,因为fetch使用了Promises

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

这种方法不仅简单,而且效率更高,因为它可以同时发出两个请求。您的方法一直等到学生被拿到,然后才拿到分数。

在MDN上查看Promise.all

2020-07-22