web-dev-qa-db-ja.com

javascriptの別のフェッチ内でフェッチを使用する

APIを取得し、その後別のAPIを呼び出します。 javascriptでこのようなコードを賢く使用していますか?

fetch(url, {
 method: 'get',
 }).then(function(response) {  
  response.json().then(function(data) {  
    fetch(anotherUrl).then(function(response) {
      return response.json();
    }).catch(function() {
      console.log("Booo");
    });
  });  
}) 
.catch(function(error) {  
  console.log('Request failed', error)  
});
28
Monala92

Fetchはプロミスを返します。 複数のプロミスを連鎖 にして、2番目のリクエストで最初のリクエストの結果を使用できます。

この例では、 SpaceX API を使用して、最新の打ち上げの情報を取得し、ロケットのIDを見つけ、ロケットの情報を取得します。

var url = 'https://api.spacexdata.com/v2/launches/latest';

var result = fetch(url, {
    method: 'get',
  }).then(function(response) {
    return response.json(); // pass the data as promise to next then block
  }).then(function(data) {
    var rocketId = data.rocket.rocket_id;

    console.log(rocketId, '\n');
  
    return fetch('https://api.spacexdata.com/v2/rockets/' + rocketId); // make a 2nd request and return a promise
  })
  .then(function(response) {
    return response.json();
  })
  .catch(function(error) {
    console.log('Request failed', error)
  })

// I'm using the result variable to show that you can continue to extend the chain from the returned promise
result.then(function(r) {
  console.log(r); // 2nd request result
});
.as-console-wrapper { max-height: 100% !important; top: 0; }
45
Ori Drori

fetch()呼び出しのネストに問題はありません。呼び出しをネストすることで何を達成しようとしているかによって異なります。

または、.then()を使用して呼び出しをチェーンすることもできます。 ネストされたPromiseの構造化方法 も参照してください。

fetch(url)
.then(function(response) { 
  return response.json()
})
.then(function(data) {   
  // do stuff with `data`, call second `fetch`
  return fetch(data.anotherUrl)
})
.then(function(response) { 
  return response.json(); 
})
.then(function(data) {
  // do stuff with `data`
})
.catch(function(error) { 
  console.log('Requestfailed', error) 
});
15
guest271314

これは、私が始めたときに私自身も含めて、Promisesで始めるときに人々がつまずく一般的な質問です。しかし、最初に...

新しい Fetch API を使用しようとしているのは素晴らしいことですが、もし私なら、jQuery AJAXまたはBackboneのオーバーライドされた実装のようなXMLHttpRequest実装を使用します既にこれらのライブラリを使用している場合は、jQueryの.ajax()の理由は、Fetch APIがまだ新しいため、この段階で実験的なためです。

そうは言っても、人々は間違いなくそれを使用しますが、「実験的」ステータスがなくなるまで、私は自分のプロダクションコードを使いません。

fetchを引き続き使用することにした場合は、 polyfill が利用可能です。 注:エラー処理を適切に機能させ、サーバーからCookieを受信するには、余分なフープをジャンプする必要があります。すでにjQueryを読み込んでいる場合、またはBackboneを使用している場合は、今のところjQueryをそのまま使用してください。とにかく完全に恐ろしいわけではありません。

今すぐコードに:

flat構造が必要です。それ以外の場合は、Promiseの要点がありません。 Promiseはネストされた非同期コールバック(コールバック地獄)ができないことを解決するため、Promiseをネストすることは必ずしも賢明ではありません。

時間と労力を節約し、読みやすいコード構造を使用するだけで、バグの少ないコードを作成できます。それはすべてではありませんが、いわばゲームの一部です。

約束は、非同期コードに、フラットインデントや1つの例外チャネルなど、同期コードの失われたプロパティのほとんどを保持させることです。

-ペトカ・アントノフ(Bluebird Promise Library)

// run async #1
asyncGetFn()
// first 'then' - execute more async code as an arg, or just accept results
// and do some other ops
.then(response => {
    // ...operate on response data...or pass data onto next promise, if needed
})
// run async #2
.then(asyncGetAnotherFn)
.then(response => {
    // ...operate on response data...or pass data onto next promise, if needed
})
// flat promise chain, followed by 'catch'
// this is sexy error handling for every 'then' above
.catch(err => {  
  console.error('Request failed', err) 
  // ...raise exeption...
  // ... or, retry promise... 
})
4
jeremiah.trein