While exploring the Fetch API, an intriguing quirk arises with the .json() method. Let's delve into why it returns a promise in certain circumstances and a direct value in others.
Consider the following snippet:
fetch(url) .then(response => { return { data: response.json(), status: response.status } }) .then(post => document.write(post.data));
Here, post.data yields a promise object, suggesting that the .json() call within the first .then() handler returns a promise.
However, if we modify the code to simply chain .json():
fetch(url) .then(response => response.json()) .then(post => document.write(post.title));
post now becomes an object, allowing direct access to the title attribute.
To unravel this mystery, we must understand the nature of promises. .json() initiates an asynchronous operation to fetch the HTTP response body as JSON, returning a promise. This promise represents the eventual availability of the JSON-parsed data.
When the promise is returned from a .then() handler (as in the first example), the promise continues to exist within the chain. However, when a value is returned (as in the second example), the promise is considered "fulfilled" and the returned value is adopted as the result of the outer .then().
To handle such situations, you can either chain the promises using nested .then()s:
fetch(url).then(response => response.json().then(data => ({ data: data, status: response.status }) ).then(res => { console.log(res.status, res.data.title) }));
Or utilize modern asynchronous keywords like async and await:
const response = await fetch(url); const data = await response.json(); console.log(response.status, data.title);
Remember to always check the HTTP response status before attempting to parse the JSON, as it may not always be in the expected format.
The above is the detailed content of Why Does Fetch's .json() Method Sometimes Return a Promise and Sometimes Return a Value?. For more information, please follow other related articles on the PHP Chinese website!