【问题标题】:How to call multiple rest requests with Axios如何使用 axios 调用多个休息请求
【发布时间】:2018-05-17 12:52:42
【问题描述】:

我是 React JS 的新手。我已经阅读了一些关于如何在 Reactjs 中创建客户端休息的示例。
我的问题 - 我获得了所有课程,然后我希望为每门课程调用另一个 HTTP 服务。我的代码如下。

export default class Courses extends Component{

    constructor(props) {
        super(props);
        this.state = {courses: []};
    }

    componentDidMount() {
        axios.get('http://localhost:8065/api/course/all')
        .then(response => {
            const courseList = response.data.map(c => {
                return {
                  id: c.id,
                  name: c.name,
                  previewBase64:c.previewBase64,
                  authors:
                     axios.get('http://localhost:8065/api/course/getAuthorsByCourseId/'+c.id+"/")
                    .then(res => {
                        const profiles = res.data.map(p => {
                            return {
                              name: p.name                       
                            };
                          })
                    })
                };
              })
              console.log(courseList);
              const newState = Object.assign({}, this.state, {
                courses: courseList
              });
              // store the new state object in the component's state
              this.setState(newState);
        }); 
    };
    render(){
        return(
            <CourseList courses={this.state.courses}/>
        )
    }
}

我的 CourseList.jsx :

const courseList = (props) => (
    <Grid>
    <Row>
        {
            props.courses.map((course, i)=>{
                return  (
                <Col key ={i} lg={2} sm={8} xs={12} md={6}>
                    <div className="course-block">
                         <p>{course.name}</p>
                         <p>AUTHOR NAME WILL BE HERE </p>
                    </div>

                </Col>)
                }) 
            }                             
    </Row>
</Grid>
);

export default courseList;

此代码有效,但我得到这样的作者的“承诺”。 {id: 7, name: "HTML", previewBase64: "", authors: Promise}

【问题讨论】:

  • 尝试等待:authors: await axios.get('http......
  • 作者对象里面有什么?
  • 在您的作者致电尝试 .subscribe 之后,而不是 .then

标签: javascript reactjs rest axios


【解决方案1】:

您需要Promise.allaxios.all

const baseURL = 'http://localhost:8065/api/course/getAuthorsByCourseId/';

const p = Promise.all(response.data.map(({ id }) => axios.get(`${baseURL}${id}`)));

p.then(result => {
  console.log(result);
}).catch(e => {
  throw e;
});

【讨论】:

    【解决方案2】:

    你可以试试下面这个,作为参考https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

    async componentWillMount() {
            let data = await axios.get('http://localhost:8065/api/course/all').then(response => {
                return response
            })
            const courseList = data.map(c => {
                return {
                    id: c.id,
                    name: c.name,
                    previewBase64: c.previewBase64,
                    authors: await axios.get('http://localhost:8065/api/course/getAuthorsByCourseId/' + c.id + "/")
                        .then(res => {
                            const profiles = res.data.map(p => {
                                return {
                                    name: p.name
                                };
                            })
                        })
                };
            })
            console.log(courseList);
            const newState = Object.assign({}, this.state, {
                courses: courseList
            });
            // store the new state object in the component's state
            this.setState(newState);
        }
    

    【讨论】:

      【解决方案3】:

      你可以尝试用这种方式重构,反正最好只有一个 API 可以同时返回课程和作者

      componentDidMount() {
          axios.get('http://localhost:8065/api/course/all')
          .then(response => {
      
            const promises = response.data.map(c => {
              axios.get('http://localhost:8065/api/course/getAuthorsByCourseId/'+c.id+"/")
              .then(res => { //for each course get the authors
                  return res.data.map(p => {
                      return {
                        name: p.name                       
                      };
                    });
              })
              .then(profiles => ({ id: c.id, profiles })); //keep a reference with the course
            });
      
            axios.all(promises, (allProfiles) => { //wait for all getAuthorsByCourseId are resolved
              const profileMap = allProfiles.reduce((map, profiles)=> {
                return map[profiles.id] = profiles.profiles;
              }, {}); // from array to map
              const courseList = response.data.map(c => {
                return {
                  id: c.id,
                  name: c.name,
                  previewBase64:c.previewBase64,
                  authors: profileMap[c.id],
                };
              }); //build the courseList with all data resolved
              const newState = Object.assign({}, this.state, {
                courses: courseList
              });
              // store the new state object in the component's state
              this.setState(newState);       
            });
          }); 
      };
      

      【讨论】:

      • 创建一个包含课程和作者的 API 不是问题。但是如果我想创建类似微服务的API,我应该把它分开吗?
      • 我认为对于这个用例,最好有一个 API,因为课程和作者是非常接近的实体,您可以通过一个请求将所有信息提供给客户端进行简单的连接(是关系db),最大限度地减少负载和网络延迟
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-26
      • 1970-01-01
      • 2021-07-13
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多