web-dev-qa-db-ja.com

Axios:複数のAPIリクエストのチェーン

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

2番目のリクエストは次のとおりです。

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

次に、3番目の要求があります。これは、完了している最初の2つに依存しています。

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

最初の2つの後に3番目の呼び出しが発生するように、これら3つの呼び出しをチェーンするにはどうすればよいですか?

23
Freddy

まず、componentWillMountでこれを実行するかどうかわからない場合は、componentDidMountに保存し、これらのリクエストで一度更新されるデフォルトの状態を保持する方が良いでしょう。次に、追加の再レンダリングを引き起こす可能性があるため、記述するsetStateの数を制限する必要があります。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,
  });

}
30
Matt Aft

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

これはすべてのgetを取得し、次のような.dataで呼び出す必要がある応答内に配置します:firstResponse.data

14

パーティーに少し遅れましたが、私は約束を連鎖するこのパターンが好きです。

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));
8
chrisz

次のようなものが必要だと思います。

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
       })
6
Morleee

パフォーマンスの向上とコードのクリーン化のため

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)
    }
}
4
Toh Ban Soon

これは、JSの Promises に関連しています。さまざまな方法で解決できます。私にとって最も簡単な方法は、各リクエストを最初から3番目にネストすることです。つまり、最初の要求から開始して、2番目のaxios.get(url)を最初の要求の.then()に入れ、3番目の要求を2番目の要求の.then()に入れる必要があります。

一般的なプロミスについては、.then()部分の内部でプロミスが解決され、responseにアクセスできることが期待されます。そのため、ネストすることで、非同期であるという問題をそれほどエレガントではない方法で解決できます。

0
milkersarac