我似乎不知道如何在循环中设置数组的值…
如下所示,我从数据库中检索了一些值,并循环遍历它们。
我在这里所要做的大致可以概括如下:
- request_1 (pk)
- 从该客户端获取所有预订id,然后
- 我得到预订列表,然后
- 循环所有预订以获取详细信息,其中包括产品的id
- request_2
- 再次遍历id并获取每个产品的详细信息
- request_3
然后我尝试存储我得到的那些值,但它不起作用。]
当我显示什么是推到循环内的数组,它似乎工作(即我得到的值意味着要检索)。然而,在循环之外,数组是完全空的…
到目前为止的代码如下:
const request = async (pk) => {
try {
let singleDetail = [];
const firstResponse = await axios.get(
`http://localhost:8000/${pk}`
);
firstResponse.data.map(async (book, idx) => {
const booking = JSON.stringify(book.id);
const secondResponse = await axios.get(
`http://localhost:8000/${booking}`
);
Object.keys(secondResponse.data).map(async (single) => {
let course = JSON.stringify(secondResponse.data[single].courses);
const thirdResponse = await axios.get(
`http://localhost:8000/${course}`
);
singleDetail.push(
JSON.stringify({
booking: booking,
single: JSON.stringify(secondResponse.data[single]),
course: JSON.stringify(thirdResponse.data),
})
);
});
});
console.log("SINGLEDETAILS " + JSON.stringify(singleDetail));
return singleDetail;
} catch (error) {
console.log(error);
}
};
从这个例子来看,问题似乎是您没有等待来自映射的异步函数。
如果不等待firstResponse.data.map(async (book, idx) => {...})
的结果,JS将跳过等待承诺解决,从而直接跳转到return singleDetail;
通过使用await Promise.all(...)
,你告诉JS等待数组中的所有承诺都成功后再继续。
试题:
const request = async (pk) => {
try {
let singleDetail = [];
const firstResponse = await axios.get(
`http://localhost:8000/${pk}`
);
await Promise.all(firstResponse.data.map(async (book, idx) => {
const booking = JSON.stringify(book.id);
const secondResponse = await axios.get(
`http://localhost:8000/${booking}`
);
await Promise.all(Object.keys(secondResponse.data).map(async (single) => {
let course = JSON.stringify(secondResponse.data[single].courses);
const thirdResponse = await axios.get(
`http://localhost:8000/${course}`
);
singleDetail.push(
JSON.stringify({
booking: booking,
single: JSON.stringify(secondResponse.data[single]),
course: JSON.stringify(thirdResponse.data),
})
);
}));
}));
console.log("SINGLEDETAILS " + JSON.stringify(singleDetail));
return singleDetail;
} catch (error) {
console.log(error);
}
};
如果单个API请求失败,try/catch将捕获错误,并且所有成功的数据请求都没有任何用处。
如果希望使用您可以捕获的任何数据(当循环中的其他请求失败时),您可以修改代码以在每个请求之后捕获错误。
如果有很多请求发生,您可能希望使用https://www.npmjs.com/package/p-map而不是await Promise.all(...)
之类的东西来限制出站连接的数量。