использование fetch внутри другой выборки в javascript

Я хочу получить 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)  
});

Ответ 1

Fetch возвращает обещание, и вы можете связать несколько обещаний и использовать результат первого запроса во втором запросе:

В этом примере используется API SpaceX, чтобы получить информацию о последнем запуске, найти идентификатор ракеты и получить информацию о ракетах.

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

Ответ 2

Нет проблем с вызовами вложенности fetch(). Это зависит от того, чего вы пытаетесь достичь, вложенных вызовов.

Вы можете альтернативно использовать .then() для цепочки вызовов. См. Также Как структурировать вложенные обещания

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

Ответ 3

Это общий вопрос, с которым люди сталкиваются, начиная с обещаний, включая меня, когда я начал. Однако сначала...

Замечательно, что вы пытаетесь использовать новый API Fetch, но если бы я был вами, я бы использовал реализацию XMLHttpRequest, например jQuery AJAX или Backbone, переопределенную реализацию jQuery .ajax(), если вы уже используете эти библиотеки. Причина в том, что API-интерфейс Fetch все еще настолько новый и, следовательно, экспериментальный на этом этапе.

С учетом сказанного, люди определенно используют его, но я не буду в своем собственном коде производства, пока он не будет "экспериментальным".

Если вы решите продолжить использование fetch, имеется полипол. ПРИМЕЧАНИЕ. Вам нужно перейти через дополнительные обручи, чтобы обеспечить правильную работу обработки ошибок и получать файлы cookie с сервера. Если вы уже загружаете jQuery или используете Backbone, просто держитесь за них; не так уж и страшно.

Теперь на код:

Вы хотите плоскую структуру, иначе вам не хватит точки обещаний. Неразумно вкладывать обещания, обязательно, потому что обещания решают, какие вложенные асинхронные обратные вызовы (callback hell) не могли.

Вы сэкономите время и энергию и получите меньше кода с ошибкой, просто используя более читаемую структуру кода. Это не все, но это часть игры, так сказать.

Обещания заключаются в том, что асинхронный код сохраняет большинство потерянных свойств синхронного кода, таких как плоский отступ и один канал исключения.

- Петька Антонов (библиотека обещаний Блюберд)

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