【发布时间】:2021-02-17 21:33:52
【问题描述】:
我正在尝试使用 github api 来获取用户的项目并在弹出窗口中列出它们。我无法弄清楚为什么 async / await 不起作用并且我最终传递的数据始终未定义。
这就是我从 api 获取数据的方式(已编辑用于...):
export default async function GitHubFetch({ userName }) {
let returnArray = [];
let response = await customFetch(
Urls.GitHub + "users/" + userName + "/repos"
);
for (const element of response) {
let project = {};
project.name = element.name;
project.description = element.description;
project.html_url = element.html_url;
let langResponse = await customFetch(element.languages_url);
project.languages = Object.keys(langResponse);
returnArray.push(project);
}
console.log("the array i'm returning from fetch is: ", returnArray);
return returnArray;
}
这个函数的returnArray的console.log是:
[{"name":"cthulu_finance","description":"stock-trading application written in react and node.js / express","html_url":"https://github.com/contip/cthulu_finance","languages":["TypeScript","HTML","CSS"]},{"name":"c_structures","description":"collection of data structures in c","html_url":"https://github.com/contip/c_structures","languages":["C"]},{"name":"masm_io_procedures","description":"Low-level implementations of string-to-int and int-to-string in x86 assembly","html_url":"https://github.com/contip/masm_io_procedures","languages":["Assembly"]}]
上述函数中的项目数组用于生成项目列表:
export default function GitHubListDisplay({ projects }) {
let listItems = [];
console.log(projects);
if (Array.isArray(projects)) {
projects.forEach((project, index) => {
listItems.push(
<>
<ListGroup.Item action href={project.html_url}>
{project.name}
</ListGroup.Item>
<ListGroup.Item>{project.description}</ListGroup.Item>
<ListGroup horizontal>{HorizontalList(project.languages)}</ListGroup>
</>
);
});
}
return <ListGroup>{listItems}</ListGroup>;
}
最后,这一切都由这个函数控制:
export default function GitHubPopUp({ userName }) {
const [projectData, setProjectData] = useState([]);
useEffect(() => {
async function fetchData() {
setProjectData(await GitHubFetch({ userName }));
console.log("the project data i fetched is: ", projectData);
}
fetchData();
}, []);
return (
<>
<OverlayTrigger
placement="right"
delay={{ show: 250, hide: 5000 }}
overlay={
<Popover>
<Popover.Title as="h3">{`GitHub Projects`}</Popover.Title>
<Popover.Content>
<strong>{userName}'s GitHub Projects:</strong>
{projectData.length > 0 && (
<GitHubListDisplay {...projectData} />
)}
</Popover.Content>
</Popover>
}
>
<Button variant="link">{userName}</Button>
</OverlayTrigger>
</>
);
}
从主控制器功能,状态最终得到正确设置,但如果我在等待 Fetch 功能结果后直接控制台记录 projectData 状态,它是未定义的.. 结果是:
the project data i fetched is: []
此外,即使我有
{projectData.length > 0 &&
在渲染 GitHubListDisplay 组件之前,console.logging 输入 projects 属性总是导致未定义。该函数永远不会显示任何内容。
有人可以帮忙吗?我花了令人尴尬的时间试图弄清楚这一点。
【问题讨论】:
-
forEach 内部使用的 'await' 永远不会阻塞主线程并执行 return 语句。所以你的 'GitHubFetch' 函数总是返回一个空数组。使用威廉指出的 promise.all()。
标签: javascript reactjs asynchronous async-await