的JavaScript。等待嵌套的提取承诺

时间:2017-11-21 18:01:04

标签: javascript wordpress promise fetch

所以我需要使用promise的结果来制作另一个fectch请求,我正在使用wordpress的其余api,我需要post对象中的子类别的id来检索该类别名称并构建两个数组一个有帖子,另一个有类别名称。 这是我的功能

function fetchAccordionData()
{   
    const id = document.querySelector('.acc').getAttribute('data-id'),
          wpRestAPI  = '/wp-json/wp/v2/';
    return fetch(wpRestAPI + 'posts?per_page=100&categories=' + id)
        .then((resp) => resp.json())
        .then((data) => 
        {
            let curId = [], subCatList = [];
            data.map((post) =>
            {
                let catList = post.categories.filter((c) => c !== parseInt(id));
                fetch(wpRestAPI + 'categories/' + catList[0])
                    .then((r) => r.json())
                    .then((cat) =>
                    {
                        if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name});
                        curId.push(cat.id);
                    });
            });
            return {'subCatList':subCatList, 'posts':data}
    });
}

现在当我调用函数时,subCatList数组还没有准备就绪:

fetchAccordionData().then((data) => 
   {
        console.log(data.subCatList, data.posts);
        for(let cat of data.subCatList)
        {
            console.log(cat);
        }
   });

那么,我如何知道第二次获取的承诺何时得到解决,以便我可以使用这些数据呢?

2 个答案:

答案 0 :(得分:1)

您需要将所有承诺放在一个数组中,然后使用Promise.all等待所有这些承诺解析,然后再访问subCatList

您修改过的代码如下所示:

function fetchAccordionData() {   

    const id = document.querySelector('.acc').getAttribute('data-id'),
          wpRestAPI  = '/wp-json/wp/v2/';

    return fetch(wpRestAPI + 'posts?per_page=100&categories=' + id)
        .then((resp) => resp.json())
        .then((data) => {

            let curId = [], subCatList = [];

            // promises is an array of promises
            let promises = data.map((post) => {

                let catList = post.categories.filter((c) => c !== parseInt(id));

                // return a promise on each iteration
                return fetch(wpRestAPI + 'categories/' + catList[0])
                    .then((r) => r.json())
                    .then((cat) =>
                    {
                        if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name});
                        curId.push(cat.id);
                    });
            });

            return Promise.all(promises)
                .then(() => ({'subCatList':subCatList, 'posts':data}));
        });
}

请注意,在{'subCatList': subCatList, 'post': data}中的每个承诺都已解决后,最后一步仅返回对象promises 。这样,您可以确信数组中的promise已完成将push转换为subCatList

同样值得注意的是fetchAccordionData的界面保持完全相同,因此您应该能够像原始示例中那样使用它:

fetchAccordionData().then((data) => {

    console.log(data.subCatList, data.posts);

    for(let cat of data.subCatList) {
        console.log(cat);
    }
});

答案 1 :(得分:0)

看起来像是

return {'subCatList':subCatList, 'posts':data} 

超出了函数中从其余API获取类别的部分:

data.map((post) =>
            {
                let catList = post.categories.filter((c) => c !== parseInt(id));
                fetch(wpRestAPI + 'categories/' + catList[0])
                    .then((r) => r.json())
                    .then((cat) =>
                    {
                        if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name});
                        curId.push(cat.id);
                    });
            });

所以你的函数在它可以从API获取类别数据之前返回它。如果你把return语句放在last语句之后,它应该返回你正在寻找的数据:

data.map((post) =>
            {
                let catList = post.categories.filter((c) => c !== parseInt(id));
                fetch(wpRestAPI + 'categories/' + catList[0])
                    .then((r) => r.json())
                    .then((cat) =>
                    {
                        if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name});
                        curId.push(cat.id);
                        return {'subCatList':subCatList, 'posts':data}
                    });
            });