web-dev-qa-db-fra.com

Pourquoi l'objet de réponse de l'API de récupération JavaScript est-il une promesse?

Lorsque vous demandez à un serveur avec une API de récupération JavaScript, vous devez faire quelque chose comme

fetch(API)
  .then(response => response.json())
  .catch(err => console.log(err))

Ici, response.json() tient sa promesse.

Le fait est que si vous voulez intercepter les erreurs de 404, Vous devez résoudre la promesse de réponse, puis rejeter la promesse de récupération, car vous ne terminerez par catch que s'il y a eu un erreur réseau. Ainsi, l'appel de récupération devient quelque chose comme

fetch(API)
  .then(response => response.ok ? response.json() : response.json().then(err => Promise.reject(err)))
  .catch(err => console.log(err))

C'est quelque chose de beaucoup plus difficile à lire et à raisonner. Ma question est donc: pourquoi est-ce nécessaire? Quel est l'intérêt d'avoir une promesse comme valeur de réponse? Y a-t-il de meilleures façons de gérer cela?

31
amb

Si votre question est "pourquoi response.json() retourne-t-il une promesse?" puis @Bergi fournit l'indice dans les commentaires: "il attend que le corps se charge".

Si votre question est "pourquoi n'est-ce pas response.json un attribut? ", alors cela aurait exigé que fetch retarde le retour de sa réponse jusqu'à ce que le corps soit chargé, ce qui pourrait être OK pour certains, mais pas pour tout le monde.

Ce polyfill devrait vous procurer ce que vous voulez:

var fetchOk = api => fetch(api)
  .then(res => res.ok ? res : res.json().then(err => Promise.reject(err)));

alors vous pouvez faire:

fetchOk(API)
  .then(response => response.json())
  .catch(err => console.log(err));

L'inverse ne peut pas être polyfilled.

22
jib