17 votes

utiliser un fetch à l'intérieur d'un autre fetch en javascript

Je veux obtenir une api et ensuite en appeler une autre. Est-il judicieux d'utiliser un code comme celui-ci en 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)  
});

34voto

Ori Drori Points 65611

Fetch renvoie une promesse, et vous pouvez chaîne de promesses multiples et utiliser le résultat de la première demande dans la deuxième demande :

L'exemple utilise le API de SpaceX pour obtenir l'info du dernier lancement, trouver l'id de la fusée, et récupérer l'info de la fusée.

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

10voto

guest271314 Points 2718

Il n'y a pas de problème d'imbrication fetch() appels. Cela dépend de ce que vous essayez d'obtenir en imbriquant les appels.

Vous pouvez également utiliser .then() pour enchaîner les appels. Voir aussi Comment structurer des promesses imbriquées

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

2voto

jeremiah.trein Points 366

C'est une question que les gens se posent souvent lorsqu'ils se lancent dans les promesses, moi y compris lorsque j'ai commencé. Cependant, d'abord...

C'est bien que tu essaies d'utiliser le nouveau API de récupération mais si j'étais vous, j'utiliserais une implémentation de XMLHttpRequest pour l'instant, comme jQuery AJAX ou l'implémentation surchargée de Backbone de l'algorithme de jQuery .ajax() si vous utilisez déjà ces bibliothèques. La raison en est que l'API Fetch est encore très récente, et donc expérimentale à ce stade.

Cela dit, il est certain que les gens l'utilisent, mais je ne l'utiliserai pas dans mon propre code de production tant qu'il ne sera pas sorti du statut "expérimental".

Si vous décidez de continuer à utiliser fetch il existe un polyfill disponible. NOTE : vous devez passer par des étapes supplémentaires pour que la gestion des erreurs fonctionne correctement et pour recevoir des cookies du serveur. Si vous chargez déjà jQuery ou si vous utilisez Backbone, restez-en là pour l'instant ; ce n'est pas complètement redoutable, de toute façon.

Passons maintenant au code :

Vous voulez un plat structure, sinon tu rates l'intérêt de Promesses. Il n'est pas sage d'imbriquer les promesses, nécessairement, parce que les promesses résolvent ce que les callbacks asynchrones imbriqués (callback hell) ne pouvaient pas faire.

Vous économiserez du temps et de l'énergie, et produirez moins de code bogué en utilisant simplement une structure de code plus lisible. Ce n'est pas tout, mais cela fait partie du jeu, pour ainsi dire.

Les promesses permettent au code asynchrone de conserver la plupart des propriétés perdues. du code synchrone, comme l'indentation plate et un canal d'exception canal.

-- Petka Antonov (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... 
})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X