我正在尝试遍历来自API调用的URL列表。如何使此代码同步?
我已经尝试在.map()迭代之前使用async / await,但是它总是会移到调度函数上。
return dispatch => {
let query = `?`;
if (currentPage) query += `page=${currentPage}`;
if (isAlive) query += `&isAlive=${isAlive}`;
if (name) query += `&name=${name}`;
dispatch(fetchCharsStart());
axios
.get(`https://www.anapioficeandfire.com/api/characters${query}`)
.then(({ data }) => data)
.then(characters => {
//Iterating all characters
characters.map(char => {
char.fetchedBooks = [];
//Iterating books for each character...
char.books.map(url => {
axios.get(url).then(({ data }) => {
console.log("Fetching...");
char.fetchedBooks.push({
name: data.name,
release: data.release
});
});
});
});
console.log("Characters: ", characters);
dispatch(fetchCharsSuccess(characters));
})
.catch(err => {
console.log(err);
dispatch(fetchCharsFail(err));
});
};
};
我期望fetchChars()的日志是Fetching...
的15倍,并且只有在此之后才是Characters数组,但是我得到了相反的行为。
答案 0 :(得分:0)
这是预期的行为:您正在遍历异步请求,但在执行以下代码之前未解决所有的Promise,因此在获取所有数据之前记录了“ Characters..."
”。
尝试async/await
时情况不错。
getCharacters = async () => {
let res = await axios.get(`https://www.anapioficeandfire.com/api/characters${query}`);
...
...
return characters;
};
您必须使用async / await链接请求,以便在执行其余代码之前,所有诺言都将得到解决。
let characters = await getCharacters();
characters.map(char => {
char.fetchedBooks = [];
//Iterating books for each character...
char.books.map(url => {
let books = await getBooks();
});
});
答案 1 :(得分:0)
export const fetchChars = (currentPage, isAlive, name) => {
return dispatch => {
let query = `?`;
if (currentPage) query += `page=${currentPage}`;
if (isAlive) query += `&isAlive=${isAlive}`;
if (name) query += `&name=${name}`;
dispatch(fetchCharsStart());
axios
.get(`https://www.anapioficeandfire.com/api/characters${query}`)
.then(({ data }) => {
return data;
})
.then(async characters => {
//Iterating all characters
for (let i = 0; i < characters.length; i++) {
characters[i].fetchedBooks = [];
//Iterating books for each character...
for (let j = 0; j < characters[i].books.length; j++) {
await axios.get(characters[i].books[j]).then(({ data }) => {
console.log("Fetching...");
characters[i].fetchedBooks.push({
name: data.name,
release: data.release
});
});
}
}
console.log("Characters: ", characters);
dispatch(fetchCharsSuccess(characters));
})
我通过使用for循环解决了。 .map()正在创建额外的功能范围,没有任何内容告诉then函数等待请求完成。现在,由于for循环不会创建功能范围,因此async关键字将与await关键字处于相同的范围。