首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用嵌套异步请求循环异步请求

用嵌套异步请求循环异步请求
EN

Stack Overflow用户
提问于 2019-02-27 11:48:18
回答 1查看 51关注 0票数 3

我有一个场景,其中我调用一个具有分页功能的API。我想做的是下面,一页一页。

  1. 调用API页面1
  2. 对于响应中的每一项,调用承诺获取更多数据并存储在数组中。
  3. 将数组发送到API
  4. 重复,直到所有页面都完成。

我目前拥有的是以下内容,但我认为我可能使这一问题复杂化太多,尽管我不确定如何进行。

代码语言:javascript
复制
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;
        })
};

目前我遇到的问题是,在调用api.mockable之前,似乎要等到所有页面都完成。此时项也是空的。

有人能提出一个办法,使这一点更整洁,并帮助我使它工作吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-27 12:00:29

如果这一切都是串行的,那么您可以只使用一个for-of循环:

代码语言:javascript
复制
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);
    }
}

我还在里面扔了些破坏和速记的东西。:-)

如果只是序列中的页面,但可以并行获取这些项,则可以在项上用for-of替换为mapPromise.all

代码语言:javascript
复制
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 data = await getItems(pSize, i);
        const items = await Promise.all(data.merchandiseList.map(async ({id, type}) => {
            const imageURL = await getImageURL(id, type);
            return {id, imageURL};
        }));
        await api.mockable('sync', items);
    }
}

async函数对map的调用作为非async函数的效率可能略高一些:

代码语言:javascript
复制
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);
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54904818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档