Axios:链接多个API请求

Fre*_*ddy 28 reactjs react-native axios

我需要从Google Maps API链接一些API请求,而我正在尝试使用Axios.

这是第一个请求,它位于componentWillMount()中

axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p1)
  .then(response => this.setState({ p1Location: response.data }))  }
Run Code Online (Sandbox Code Playgroud)

这是第二个请求:

axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p2)
  .then(response => this.setState({ p2Location: response.data }))
Run Code Online (Sandbox Code Playgroud)

然后我们有第三个请求,这取决于前两个完成:

axios.get('https://maps.googleapis.com/maps/api/directions/json?origin=place_id:' + this.state.p1Location.results.place_id + '&destination=place_id:' + this.state.p2Location.results.place_id + '&key=' + 'API-KEY-HIDDEN')
  .then(response => this.setState({ route: response.data }))
Run Code Online (Sandbox Code Playgroud)

如何将这三个调用链接起来,以便第三个调用在前两个调用之后发生?

Mat*_*Aft 35

首先,不确定是否要在您的内容中执行此操作componentWillMount,因为在完成所有这些操作之后,您的组件将不会呈现,所以最好将其放入componentDidMount并具有一些默认状态,这些状态将在完成这些请求后更新.其次,您希望限制您编写的setStates的数量,因为它们可能会导致其他重新渲染,这是使用async/await的解决方案:

async componentDidMount() {

  // Make first two requests
  const [firstResponse, secondResponse] = await Promise.all([
    axios.get(`https://maps.googleapis.com/maps/api/geocode/json?&address=${this.props.p1}`),
    axios.get(`https://maps.googleapis.com/maps/api/geocode/json?&address=${this.props.p2}`)
  ]);

  // Make third request using responses from the first two
  const thirdResponse = await axios.get('https://maps.googleapis.com/maps/api/directions/json?origin=place_id:' + firstResponse.data.results.place_id + '&destination=place_id:' + secondResponse.data.results.place_id + '&key=' + 'API-KEY-HIDDEN');

  // Update state once with all 3 responses
  this.setState({
    p1Location: firstResponse.data,
    p2Location: secondResponse.data,
    route: thirdResponse.data,
  });

}
Run Code Online (Sandbox Code Playgroud)

  • @Dravidian,您可以将 .catch 包装在 try/catch 中,或者将 .catch 链接到 Promise.all 上。如果您想处理其中一个失败而其他通过的情况,您也可以使用“allSettled”而不是“all”。并且您可能还需要更多关于在第三个请求中使用之前实际存在的“firstResponse.data.results.place_id”值的逻辑。但总体思路就在那里 (5认同)
  • 如果第一个请求(仅获取第一个响应)出现错误,此模式如何处理这种情况? (4认同)
  • 完美的。这很棒。 (2认同)

Ric*_*lez 14

你用过axios.all吗?您可以尝试类似的东西:

axios.all([axios.get(`firstrequest`),
           axios.get(`secondrequest`),
           axios.get(`thirdrequest`)])
     .then(axios.spread((firstResponse, secondResponse, thirdResponse) => {  
         console.log(firstResponse.data,secondResponse.data, thirdResponse.data);
     }))
     .catch(error => console.log(error));
Run Code Online (Sandbox Code Playgroud)

这将获取所有你的get并将它放在一个必须使用.data调用的响应中: firstResponse.data

  • 如果“secondrequest”的输入来自“firstrequest”的响应怎么办? (6认同)
  • 请记住,这已被弃用,axios 官方文档建议使用``Promise.all``` (3认同)

chr*_*isz 11

聚会晚了一点,但我喜欢这种将承诺链接起来的方式,将它们返回以使承诺链保持活力。

axios
  .get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p1')
  .then(response => {
    this.setState({ p1Location: response.data });
    return axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p2');
  })
  .then(response => {
    this.setState({ p2Location: response.data });
    return axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p3');
  })
  .then(response => {
    this.setState({ p3Location: response.data });
  }).catch(error => console.log(error.response));
Run Code Online (Sandbox Code Playgroud)


Mor*_*eee 7

我认为您需要这样的东西:

const firstRequest = axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p1)
      .then(response => this.setState({ p1Location: response.data }))  }

const secondRequest = axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p2)
  .then(response => this.setState({ p2Location: response.data }))

const thirdRequest = axios.get('https://maps.googleapis.com/maps/api/directions/json?origin=place_id:' + this.state.p1Location.results.place_id + '&destination=place_id:' + this.state.p2Location.results.place_id + '&key=' + 'API-KEY-HIDDEN')
  .then(response => this.setState({ route: response.data }))


Promise.all([firstRequest, secondRequest])
       .then(() => {
           return thirdRequest
       })
Run Code Online (Sandbox Code Playgroud)


Toh*_*oon 5

为了获得更好的性能和更

简洁的代码:1.使用promise.all()或axios.all()同时执行request1和request2。因此request2将在不等待request1响应的情况下执行。request1和request2返回响应后,request3将基于返回的响应数据作为参数继续执行。
2.模板字符串使用反引号(``)

async componentDidMount(){
    try{
        const [request1, request2] = await Promise.all([
           axios.get(`https://maps.googleapis.com/maps/api/geocode/json?&address=${this.props.p1}`),
           axios.get(`https://maps.googleapis.com/maps/api/geocode/json?&address=${this.props.p2}`)
        ]);

        const request3 = await axios.get(`https://maps.googleapis.com/maps/api/directions/json?origin=place_id:${request1.data.results.place_id}&destination=place_id:${request2.data.results.place_id}&key=${API-KEY-HIDDEN}`);
        console.log(request3);
    }
    catch(err){
        console.log(err)
    }
}
Run Code Online (Sandbox Code Playgroud)