J'ai joué avec le fetch()
récemment déconné API et remarqué quelque chose d'un peu bizarre.
let url = "http://jsonplaceholder.typicode.com/posts/6";
let iterator = fetch(url);
iterator
.then(response => {
return {
data: response.json(),
status: response.status
}
})
.then(post => document.write(post.data));
;
post.data
renvoie un Promise
objet.
http://jsbin.com/wofulo/2/edit?js,output
Cependant s'il s'écrit:
let url = "http://jsonplaceholder.typicode.com/posts/6";
let iterator = fetch(url);
iterator
.then(response => response.json())
.then(post => document.write(post.title));
;
post
voici un standard Object
auquel vous pouvez accéder à l'attribut title.
http://jsbin.com/wofulo/edit?js,output
Donc ma question est: pourquoi response.json
renvoie une promesse dans un objet littéral, mais renvoie la valeur si elle vient d'être renvoyée?
javascript
asynchronous
promise
fetch-api
Haveacigaro
la source
la source
response.json()
promesse peut être rejetée si la réponse n'est pas JSON valide.Réponses:
Parce que vous recevez le
response
dès que tous les en-têtes sont arrivés. L'appel.json()
vous donne une autre promesse pour le corps de la réponse http qui n'a pas encore été chargée. Voir aussi Pourquoi l'objet de réponse de l'API JavaScript Fetch est-il une promesse? .Parce que c'est ainsi que fonctionnent les promesses . La possibilité de renvoyer les promesses du rappel et de les faire adopter est leur caractéristique la plus pertinente, elle les rend chaînables sans imbrication.
Vous pouvez utiliser
ou toute autre approche pour accéder à la promesse précédente entraîne une chaîne .then () pour obtenir l'état de la réponse après avoir attendu le corps json.
la source
JSON.parse()
place deres.json()
??res.json()
est essentiellement un raccourci pourres.text().then(JSON.parse)
. Les deux attendent les données à l'aide d'une promesse et analysent le json.Cette différence est due au comportement des promesses plus que
fetch()
spécifiquement.Lorsqu'un
.then()
rappel renvoie un supplémentairePromise
, le suivant.then()
rappel dans la chaîne est essentiellement lié à cette promesse, recevant sa résolution ou son rejet et sa valeur.Le 2ème extrait de code aurait également pu être écrit comme suit:
Dans ce formulaire comme dans le vôtre, la valeur de
post
est fournie par la promesse renvoyée parresponse.json()
.Lorsque vous retournez un plaine
Object
, cependant,.then()
considère que le résultat est réussi et se résout immédiatement, semblable à:post
dans ce cas, c'est simplement le queObject
vous avez créé, qui détient unPromise
dans sadata
propriété. L’attente que cette promesse se réalise est encore incomplète.la source
En outre, ce qui m'a aidé à comprendre ce scénario particulier que vous avez décrit est la documentation de l' API Promise , en particulier où elle explique comment la promesse retournée par la
then
méthode sera résolue différemment en fonction de ce que le gestionnaire fn renvoie:la source
En plus des réponses ci-dessus, voici comment vous pouvez gérer une réponse de la série 500 de votre API où vous recevez un message d'erreur encodé en json:
la source