我最近一直在讨论fetch()
api,并注意到一些有点古怪的东西。
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
会返回Promise
个对象。
http://jsbin.com/wofulo/2/edit?js,output
但如果写成:
let url = "http://jsonplaceholder.typicode.com/posts/6";
let iterator = fetch(url);
iterator
.then(response => response.json())
.then(post => document.write(post.title));
;
post
这里是标准Object
,您可以访问title属性。
http://jsbin.com/wofulo/edit?js,output
所以我的问题是:为什么response.json
会在对象文字中返回一个promise,但是如果刚刚返回则返回值?
答案 0 :(得分:115)
为什么
response.json
会返回承诺?
因为当所有标头到达时您收到response
。调用.json()
可以获得尚未加载的http响应正文的承诺。另请参阅Why is the response object from JavaScript fetch API a promise?。
如果我从
then
处理程序返回承诺,为什么我会得到这个值?
因为that's how promises work。从回调中返回promises并获取它们的能力是它们最相关的特性,它使它们可以链接而不需要嵌套。
您可以使用
fetch(url).then(response =>
response.json().then(data => ({
data: data,
status: response.status
})
).then(res => {
console.log(res.status, res.data.title)
}));
等待json正文后,或任何其他approaches to access previous promise results in a .then() chain获取响应状态。
答案 1 :(得分:12)
这种差异是由于Promises的行为特别是fetch()
。
当.then()
回调返回额外的Promise
时,链中的下一个.then()
回调基本上绑定到该Promise,接收其解析或拒绝履行和值。
第二个片段也可以写成:
iterator.then(response =>
response.json().then(post => document.write(post.title))
);
在此表单和您的表单中,post
的值由response.json()
返回的承诺提供。
但是当您返回普通Object
时,.then()
认为成功的结果会立即自行解决,类似于:
iterator.then(response =>
Promise.resolve({
data: response.json(),
status: response.status
})
.then(post => document.write(post.data))
);
在这种情况下, post
只是您创建的Object
,其Promise
属性中包含data
。等待履行承诺的工作仍然不完整。
答案 2 :(得分:7)
另外,有什么帮助我理解你描述的这个特定场景是Promise API documentation,特别是它解释了then
方法返回的承诺将如何以不同的方式解决,具体取决于< strong> handler fn 返回:
如果处理函数:
- 返回一个值,然后返回的promise将以返回值作为其值进行解析;
- 抛出错误,然后返回的promise将被抛出错误作为其值被拒绝;
- 返回已经解决的承诺,然后返回的承诺将以该承诺的值作为其值来解决;
- 返回已被拒绝的承诺,然后返回的承诺将被拒绝,并将该承诺的值作为其值。
- 返回另一个待处理的promise对象,然后返回的promise的解析/拒绝将在 解析/拒绝处理程序返回的承诺。而且, 当时返回的promise的值将与value的值相同 处理程序返回的承诺。
答案 3 :(得分:5)
除了上面的答案之外,这里是你如何处理来自api的500系列响应,你会收到以json编码的错误信息:
function callApi(url) {
return fetch(url)
.then(response => {
if (response.ok) {
return response.json().then(response => ({ response }));
}
return response.json().then(error => ({ error }));
})
;
}
let url = 'http://jsonplaceholder.typicode.com/posts/6';
const { response, error } = callApi(url);
if (response) {
// handle json decoded response
} else {
// handle json decoded 500 series response
}
答案 4 :(得分:-1)
我刚刚找到的另一个选项是:
“信息”是最终回复:)
答案 5 :(得分:-1)
也将 await 与 responce.json() 一起使用
const responce = await fetch(url);
const result = await responce.json();
也将 await 与 responce.json() 一起使用