gpt4 book ai didi

reactjs - 异步等待不等待 useEffect 内的响应

转载 作者:行者123 更新时间:2023-12-02 19:18:15 25 4
gpt4 key购买 nike

我正在为黑客新闻创建简单的克隆,我想使用 useEffect 并在其中返回 id,然后使用这些 id 获取前 50 个帖子。

问题在于 fetchHackerNewsPosts 中的第二个函数,它没有等待它在 postsArray 中添加数据,而是将其打印为空。

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function App() {
const [posts, setPosts] = React.useState([]);

React.useEffect(() => {
let postsArray = [];

async function fetchHackerNewsPosts() {
try {
// it waits this function
let postsIDsArray = await fetch(
"https://hacker-news.firebaseio.com/v0/topstories.json"
)
.then((res) => res.json())
.then((result) => {
return result;
});

// it doesn't wait this function
await postsIDsArray.slice(0, 50).map((postId) => {
fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`)
.then((res) => res.json())
.then((result) => {
postsArray.push(result);
});
});
} catch (error) {
console.log(error);
}
}

fetchHackerNewsPosts();
console.log(postsArray);
}, []);

return (
<div className="p-10">
<header className="">
<h1> Hacker news API </h1>
</header>
<div className="bg-blue-600">list</div>
</div>
);
}

export default App;

最佳答案

我认为这里有两个问题。

1 - 您正在等待的函数不是异步函数。您正在执行 post postsIDsArray.slice(0, 50).map(...) - 这只会解析为空数组(您不会返回提取)。您可以返回获取的内容,然后您将获得一组 promise ,然后您可以通过 Promise.all 等待:

await Promise.all(postsIDsArray.slice(0, 50).map((postId) => fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`)
.then((res) => res.json())
.then((result) => {
postsArray.push(result);
}));

这仍然会在您 console.log(postsArray); 的位置记录一个空数组 - 因为您没有等待 fetchHackerNewsPosts。

可能值得考虑使用所有等待/异步风格或所有 promise 风格,而不是混合两者。 ~~然而,这通常意味着切换到常规循环而不是map/forEach,所以你可以在中间等待。~~ - 编辑 - 删除,欢呼Lione

React.useEffect(() => {
async function fetchHackerNewsPosts() {
const posts = [];

try {
const postIDsResponse = await fetch(
"https://hacker-news.firebaseio.com/v0/topstories.json"
);

const postIDs = await postIDsResponse.json();

for (const postID of postIDs) {
const postResponse = await fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`);
const post = await post.json();
posts.push(post);
}

return posts;
} catch (error) {
console.log(error);
}
}

setPosts(await fetchHackerNewsPosts());
}, []);

正如所指出的 - Promise.all 实际上可能会快得多,因为您不需要等待上一个请求完成后再触发下一个请求。

React.useEffect(() => {
async function fetchHackerNewsPosts() {
try {
const postIDsResponse = await fetch(
"https://hacker-news.firebaseio.com/v0/topstories.json"
);

const postIDs = await postIDsResponse.json();

const postRequests = postIDs.map(async postID => {
const postResponse = await fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`);
return await post.json();
});

return await Promise.all(postRequests);
} catch (error) {
console.log(error);
}
}

const posts = await fetchHackerNewsPosts();
setPosts(posts);
}, []);

关于reactjs - 异步等待不等待 useEffect 内的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63398305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com