问题描述
在下面的代码中,为什么我在最后一行得到一个未定义的?如何编写以获取变量a中的响应
function getData(){
const url = "https://jsonplaceholder.typicode.com/users";
url2='https://jsonplaceholder.typicode.com/posts/'
fetch(url).then((res) =>{
res.json().then((dataAsJson) => {
return(dataAsJson[0].id);
})
.then((id)=>{
fetch(url2+"/"+id).then((res)=> {
return res.json().then((data) => {
return(data);
})
})
})
})
}
var a = getData();
console.log(a)```
解决方法
您缺少两个return语句,实际上将值从一个promise传递到下一个promise。因此,要使代码正常工作,您必须将它们包括在内:
async function getData(){
const url = "https://jsonplaceholder.typicode.com/users";
url2='https://jsonplaceholder.typicode.com/posts/'
const data = await fetch(url).then((res) =>{
return res.json().then((dataAsJson) => {
return(dataAsJson[0].id);
})
.then((id)=>{
return fetch(url2+"/"+id).then((res)=> {
return res.json().then((data) => {
return(data);
})
})
})
})
}
这里的另一个提示:从承诺中返回时,无论是其他承诺还是简单的值都没关系-下一个then
调用将始终获取未包装的值。因此,您实际上不必嵌套所有这些promise调用。如果这样说,它将更容易阅读:
const url = "https://jsonplaceholder.typicode.com/users";
url2='https://jsonplaceholder.typicode.com/posts/'
const data = await fetch(url)
.then((res) =>{ return res.json()})
.then((dataAsJson) => { return(dataAsJson[0].id); })
.then((id)=>{ return fetch(url2+"/"+id); })
.then((res)=> { return res.json(); })
还有:由于您仅在每个回调中返回一个值,因此可以利用JavaScript-Arrow-Function功能,该功能会在只有一个表达式的情况下自动返回,并将其进一步缩短为该表达式:
const url = 'https://jsonplaceholder.typicode.com/users';
url2 = 'https://jsonplaceholder.typicode.com/posts/';
const data = await fetch(url)
.then(res => res.json())
.then(dataAsJson => dataAsJson[0].id)
.then(id => fetch(`${url2}/${id}`))
.then(res => res.json());
可读性更好,更容易发现错误。 :)
更新:我完全忽略了您的代码,您试图从异步getData()
函数中同步读取。 @幽灵在他的回答中澄清了这一点-因此这应该被接受。但是,为了不让错误的代码站起来,我在答案中编辑了正确的行为。
您应该可以使用await
来简化该功能。
它消除了对嵌套回调的需要。该代码未经测试,但理论上应该可以工作。
async function getData() {
const url = "https://jsonplaceholder.typicode.com/users";
const url2 = "https://jsonplaceholder.typicode.com/posts/";
const firstFetch = await fetch(url)
const firstResult = await firstFetch.json();
const id = firstResult[0].id;
const secondFetch = await fetch(url2 + "/" + id)
return await secondFetch.json();
}
https://javascript.info/async-await
您也可以创建一个新的Promise,以在第二次获取时解决。但是这种方法比较麻烦
,由于您没有从getData()
返回任何内容,因此变得不确定。
Promises及其链接的方法then()
和catch
会自己返回Promise的一个实例,而不是您从then()
的回调中返回的数据。
要获得您期望的行为,一种方法是使用async
和await
。 David带大卫,您会这样做:
const url = 'https://jsonplaceholder.typicode.com/users';
const url2 = 'https://jsonplaceholder.typicode.com/posts/';
const data = await fetch(url)
.then(res => res.json())
.then(dataAsJson => dataAsJson[0].id)
.then(id => fetch(`${url2}/${id}`))
.then(res => res.json());
console.log(data);