Javascript 使用嵌套异步请求循环异步请求
我有一个场景,我调用一个具有分页的API。 我想做的是如下,一次一页Javascript 使用嵌套异步请求循环异步请求,javascript,node.js,ecmascript-6,async-await,Javascript,Node.js,Ecmascript 6,Async Await,我有一个场景,我调用一个具有分页的API。 我想做的是如下,一次一页 调用API第1页 对于响应中的每个项,调用承诺以获取更多数据并存储在数组中 将数组发送到API 重复此步骤,直到完成所有页面 我目前拥有的是以下内容,但我认为我可能把这件事复杂化了太多,尽管不确定如何继续 export const importData = async() { const pSize = 15; const response = await getItems(pSize, 1); con
export const importData = async() {
const pSize = 15;
const response = await getItems(pSize, 1);
const noPage = Math.ceil(response.totalMerchandiseCount/pSize);
for (let i = 1; i < noPage; i++) {
const items = [];
const data = await getItems(pSize, i);
await async.each(data.merchandiseList, async(i, cb) => {
const imageURL = await getImageURL(i.id, i.type);
items.push({
id: i.id,
imageURL: imageURL,
});
cb();
}, async() => {
return await api.mockable('sync', items);
});
}
}
export const getImageURL = async(id, type) => {
let url = `https://example.com/${id}`;
return axios.get(url)
.then((response) => {
const $ = cheerio.load(response.data);
// do stuff to get imageUrl
return image;
})
.catch((e) => {
console.log(e);
return null;
})
};
export const importData=async(){
常数pSize=15;
const response=wait getItems(pSize,1);
const noPage=Math.ceil(response.totalMerchandiseCount/pSize);
for(设i=1;i{
const-imageURL=wait-getImageURL(i.id,i.type);
推({
id:i.id,
imageURL:imageURL,
});
cb();
},async()=>{
返回等待api.mockable('sync',项);
});
}
}
导出常量getImageURL=async(id,类型)=>{
让url=`https://example.com/${id}`;
返回axios.get(url)
。然后((响应)=>{
const$=cheerio.load(response.data);
//做一些事情来获取imageUrl
返回图像;
})
.catch((e)=>{
控制台日志(e);
返回null;
})
};
我目前的问题是,似乎要等到所有页面都完成后才能调用api.mockable。此时项也为空
有谁能建议一种方法使它更整洁一点并帮助我工作吗?如果这一切都是串行的,那么您可以使用
for of
循环:
export const importData = async() {
const pSize = 15;
const response = await getItems(pSize, 1);
const noPage = Math.ceil(response.totalMerchandiseCount/pSize);
for (let i = 1; i < noPage; i++) { // Are you sure this shouldn't be <=?
const items = [];
const data = await getItems(pSize, i);
for (const {id, type} of data.merchandiseList) {
const imageURL = await getImageURL(id, type);
items.push({id, imageURL});
}
await api.mockable('sync', items);
}
}
对于map
的async
函数调用,作为一个非async
函数,可以稍微提高效率:
export const importData = async() {
const pSize = 15;
const response = await getItems(pSize, 1);
const noPage = Math.ceil(response.totalMerchandiseCount/pSize);
for (let i = 1; i < noPage; i++) {
const data = await getItems(pSize, i);
const items = await Promise.all(data.merchandiseList.map(({id, type}) =>
getImageURL(id, type).then(imageURL => ({id, imageURL}))
));
await api.mockable('sync', items);
}
}
export const importData=async(){
常数pSize=15;
const response=wait getItems(pSize,1);
const noPage=Math.ceil(response.totalMerchandiseCount/pSize);
for(设i=1;i
getImageURL(id,type).then(imageURL=>({id,imageURL}))
));
等待api.mockable('sync',项);
}
}
你想一页接一页还是并行地完成这些页面?旁注-这可能比你想要的少了一页:for(让i=1;i
。通常是“从0开始,在某些地方使用async
作为标识符(async.each
)。这是来自Axios?还是其他什么?@T.J.Crowder这些页面应该一个接一个地打开。获取第一页,获取额外数据,发送数据,等待响应,下一页。async。每个页面都来自异步库,尽管我仍然不确定是否需要它,或者它是否复杂。(如果您在最后一个代码块中看到i.id
和i.type
,或者它们中的任何一个,请点击refresh.Editing error。)完美,串行页面和并行项目都可以工作。谢谢:)
export const importData = async() {
const pSize = 15;
const response = await getItems(pSize, 1);
const noPage = Math.ceil(response.totalMerchandiseCount/pSize);
for (let i = 1; i < noPage; i++) {
const data = await getItems(pSize, i);
const items = await Promise.all(data.merchandiseList.map(({id, type}) =>
getImageURL(id, type).then(imageURL => ({id, imageURL}))
));
await api.mockable('sync', items);
}
}