使用ReactJS,我尝试获得两个不同的API点并进行重组:students和scores。它们都是对象的数组。
students
scores
我的目标是 :首先,获取学生和分数,然后,将学生和分数保存在状态中,我将对其进行修改,并基于学生和分数状态创建一个新状态。总之,我有3个功能:getStudents,getScores,和rearrangeStudentsAndScores。getStudents并且getScores需要完成后rearrangeStudentsAndScores才能运行。
getStudents
getScores
rearrangeStudentsAndScores
我的问题是 :有时rearrangeStudentsAndScores会在getScores完成之前运行。搞砸rearrangeStudentsAndScores了 但是有时它会完成。不知道为什么它会在50%的时间内工作,但是我需要使其在100%的时间内工作。
这是我必须fetch students and scores在Client文件中执行的操作:
fetch
students and scores
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) };
然后,我将它们组合在一起:
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; ... } }
不知何故,到我到达的时候rearrangeStudentsWithScores,this.state.scores仍然会[]。
rearrangeStudentsWithScores
this.state.scores
[]
在运行之前,如何确保this.state.students和this.state.scores都已加载rearrangeStudentsWithScores?
this.state.students
您的代码混合了继续回调和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
Promise.all