我使用这个API http://www.omdbapi.com/,它一次只返回10个搜索结果,但提供了可用对象的总数。可以添加"页面"。参数
一个API调用搜索"star"将看起来像这样(链接不起作用,它不是一个有效的API密钥):
http://www.omdbapi.com/?apikey=keykey&s=star
并且记住特定的页面:
"http://www.omdbapi.com/?apikey=keykey&s=star&page=7"
因此,在没有指定page参数的情况下,我将以以下格式接收数据:
{
Search: [...], // An array of the first 10 search result
totalResults: "n" // The total number of result
Response: "True" // The status of the response
}
如何循环遍历所有页面并按顺序获取所有搜索数组?现在我有这个:
const [loading, setLoading] = useState(true);
const [data, setData] = useState();
const fetchMovies = async () => {
setLoading(true);
const url = `http://www.omdbapi.com/?apikey=${API_KEY}&s=${searchResult}`;
try {
const response = await fetch(url);
const data = await response.json();
let movies;
const rounding = Math.ceil(data.totalResults / 10);
if (rounding > 1) {
for (let index = 1; index <= rounding; index++) {
const response = await fetch(`${url}&page=${index}`);
const data = await response.json();
const movies = [...movies, ...data.Search];
}
}
setData(movies);
setLoading(false);
} catch (error) {
console.log(error);
setLoading(false);
}
};
useEffect(() => {
fetchMovies();
}, []);
此时循环"工作";在某种程度上,数据。搜索数组被添加到movies"但是,当代码继续执行时,setData()被设置为none, setLoading()被设置为false, fetchMovies()返回。
我知道这一点,因为如果你在循环中记录电影,你可以看到数据被添加。
我如何等待所有API调用在恢复执行之前解决,是否有可能在第一次获取中完成?还是首先需要获得页面数,然后将API调用排队?
您再次在for
循环中声明影片,但在setData(movies)
中将上述声明的影片设置为let movies;
const [loading, setLoading] = useState(true);
const [data, setData] = useState();
const fetchMovies = async () => {
setLoading(true);
const url = `http://www.omdbapi.com/?apikey=${API_KEY}&s=${searchResult}`;
try {
const response = await fetch(url);
const data = await response.json();
let movies = []; // Set empty array here
const rounding = Math.ceil(data.totalResults / 10);
if (rounding > 1) {
for (let index = 1; index <= rounding; index++) {
const response = await fetch(`${url}&page=${index}`);
const data = await response.json();
// You would want to push movies inside the movies array
movies.push(...data.Search);
}
}
setData(movies);
setLoading(false);
} catch (error) {
console.log(error);
setLoading(false);
}
};
useEffect(() => {
fetchMovies();
}, []);