我最近一直在摆弄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));
;
职位。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是一个标准的对象,你可以访问它的title属性。
http://jsbin.com/wofulo/edit?js,output
所以我的问题是:为什么反应。Json返回一个承诺在一个对象字面量,但返回值如果刚刚返回?
为什么会反应。Json返回承诺?
因为当所有的报头到达时,您就会收到响应。调用.json()会为尚未加载的http响应正文提供另一个承诺。参见为什么从JavaScript获取API的响应对象是一个承诺?。
如果我从当时的处理程序返回承诺,为什么我得到这个值?
因为这就是承诺的作用。从回调中返回承诺并让它们被采用的能力是它们最相关的特性,它使它们无需嵌套即可链接。
你可以使用
fetch(url).then(response =>
response.json().then(data => ({
data: data,
status: response.status
})
).then(res => {
console.log(res.status, res.data.title)
}));
或者任何其他访问之前promise的方法都会导致.then()链,以便在等待json正文后获得响应状态。
这种差异主要是由于Promises的行为而不是fetch()。
当.then()回调返回一个额外的Promise时,链中的下一个.then()回调本质上绑定到该Promise,接收它的解决或拒绝实现和值。
第二段也可以写成:
iterator.then(response =>
response.json().then(post => document.write(post.title))
);
在这个表单和你的表单中,post的值都是由response.json()返回的Promise提供的。
然而,当你返回一个普通对象时,.then()认为这是一个成功的结果,并立即解析自己,类似于:
iterator.then(response =>
Promise.resolve({
data: response.json(),
status: response.status
})
.then(post => document.write(post.data))
);
在本例中,post只是您创建的对象,它的data属性中包含一个Promise。对实现这一承诺的等待仍未完成。
为什么会反应。Json返回承诺?
因为当所有的报头到达时,您就会收到响应。调用.json()会为尚未加载的http响应正文提供另一个承诺。参见为什么从JavaScript获取API的响应对象是一个承诺?。
如果我从当时的处理程序返回承诺,为什么我得到这个值?
因为这就是承诺的作用。从回调中返回承诺并让它们被采用的能力是它们最相关的特性,它使它们无需嵌套即可链接。
你可以使用
fetch(url).then(response =>
response.json().then(data => ({
data: data,
status: response.status
})
).then(res => {
console.log(res.status, res.data.title)
}));
或者任何其他访问之前promise的方法都会导致.then()链,以便在等待json正文后获得响应状态。
此外,帮助我理解你所描述的这个特定场景的是Promise API文档,特别是它解释了then方法返回的promises将如何根据处理程序fn返回的内容进行不同的解析:
if the handler function:
returns a value, the promise returned by then gets resolved with the returned value as its value;
throws an error, the promise returned by then gets rejected with the thrown error as its value;
returns an already resolved promise, the promise returned by then gets resolved with that promise's value as its value;
returns an already rejected promise, the promise returned by then gets rejected with that promise's value as its value.
returns another pending promise object, the resolution/rejection of the promise returned by then will be subsequent to the
resolution/rejection of the promise returned by the handler. Also, the
value of the promise returned by then will be the same as the value of
the promise returned by the handler.