从链式axios请求合并两个数组

时间:2019-02-18 07:59:08

标签: javascript arrays object axios chain

我将一堆axios获取请求链接到一个API的不同端点,并且试图从数据中创建一个类似这样的数组(简化):

[
    {
        name: "John",
        id: 1,
        gender: "male"
    },
    {
        name: "Anna",
        id: 2,
        gender: "female"
    },
]

在其中一个请求中,我按以下方式检索每个人的姓名和ID:

[
    {
        name: "John",
        id: 1
    },
    {
        name: "Anna",
        id: 2
    },
]

现在,我只需要通过在两个单独的请求中将每个人的ID发送给端点来获取性别。

我已经花了几个小时尝试使用push()和then()在顶部构造数组,但是我做对了。

我该如何处理?

我正在像这样顺便链接axios请求:

axios.get('api/' + endpoint1]).then(response => {
    axios.get('api/' + endpoint2).then(response => {
        axios.get('api/' + endpoint3).then(response => {
            // and so on...
         });
    });
});

更新1:

我觉得我没有正确解释问题。从最后的承诺开始,这就是我的代码现在的样子。我如何更改它以使数组位于问题的顶部?

.then(response => {

    people= response.data; // Array of people including their name id (not their gender though)

    for (var key in people) {

        var person = {};

        person["name"] = people[key].node.name;

        person["id"] = people[key].node.id;

        finalArray.push(person);

        axios.get('api/' + endpoint3, { // Endpoint for getting a persons gender from id
            params: {
                personId: person.id
                }
        }).then(response => {

            // I don't know what to do here...            

        });

    }

    console.log(finalArray); // Gives me an array of objects without "gender".

});

更新2:

非常感谢您的回答!

我已经结合了您的一些解决方案,这就是我的 real 代码现在的外观。对http://api.ntjp.se/coop/api/v1/serviceProducers.json的请求未发送。 为什么?

我也不希望在调用http://api.ntjp.se/coop/api/v1/serviceProducers.json之前将整个对象保留在合作响应数组中。我只想从每个对象中保存两个特定的键/值对。这两个键/值对都在每个响应对象中的一个名为“ serviceContract”的对象内。 如何保存它们?

<html>

<head>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>

    <script>

        getConnectionStatusData();

        async function getConnectionStatusData() {

            let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
                                        params: {
                                            namespace: "crm:scheduling"
                                        }
                                    });

            serviceDomainId = serviceDomains.data[0].id;

            let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
                                        params: {
                                            platform: "NTJP",
                                            environment: "PROD"
                                        }
                                    });

            connectionPointId = connectionPoints.data[0].id;

            let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
                                        params: {
                                            logicalAdress: "SE2321000016-167N",
                                            serviceConsumerHSAId: "SE2321000016-92V4",
                                            connectionPointId: connectionPointId
                                        }
                                    });

            logicalAddressId = logicalAddresss.data[0].id;

            let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId
                                        }
                                    });

            consumer = serviceConsumers.data.filter(obj => {
                  return obj.hsaId === "SE2321000016-92V4"
                });

            serviceConsumerId = consumer[0].id;

            let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId,
                                            serviceDomainId: serviceDomainId,
                                            serviceConsumerId: serviceConsumerId,
                                            include: "serviceContract"
                                        }
                                    });

            for(var idx in cooperations.data) {

                var data = async () => { return await axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId,
                                            serviceDomainId: serviceDomainId,
                                            serviceConsumerId: serviceConsumerId,
                                            serviceContractId: cooperations.data[idx].serviceContract.id
                                        }
                                    }) }
                cooperations.data[idx].producerDescription = data.description;
                cooperations.data[idx].producerHSAId = data.hsaId;
            }

            console.log(cooperations.data);

        }

    </script>

</body>

更新3

我终于使它起作用了,但是为什么当我最后将其推入finalResult时必须引用诸如response.data[0].description之类的数据?我的意思是,为什么response.data.description不能像@Cold Cerberus一样起作用?

除此之外,我的代码还可以吗,或者我做错了什么?

谢谢大家!

<html>

<head>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>

    <script>

        getConnectionStatusData();

        async function getConnectionStatusData() {

            let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
                                        params: {
                                            namespace: "crm:scheduling"
                                        }
                                    });

            serviceDomainId = serviceDomains.data[0].id;

            let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
                                        params: {
                                            platform: "NTJP",
                                            environment: "PROD"
                                        }
                                    });

            connectionPointId = connectionPoints.data[0].id;

            let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
                                        params: {
                                            logicalAdress: "SE2321000016-167N",
                                            serviceConsumerHSAId: "SE2321000016-92V4",
                                            connectionPointId: connectionPointId
                                        }
                                    });

            logicalAddressId = logicalAddresss.data[0].id;

            let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId
                                        }
                                    });

            consumer = serviceConsumers.data.filter(obj => {
                  return obj.hsaId === "SE2321000016-92V4"
                });

            serviceConsumerId = consumer[0].id;

            let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId,
                                            serviceDomainId: serviceDomainId,
                                            serviceConsumerId: serviceConsumerId,
                                            include: "serviceContract"
                                        }
                                    });

            var finalData = [];

            cooperations.data.forEach(function(cooperation) {

                axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
                            params: {
                                connectionPointId: connectionPointId,
                                logicalAddressId: logicalAddressId,
                                serviceDomainId: serviceDomainId,
                                serviceConsumerId: serviceConsumerId,
                                serviceContractId: cooperation.serviceContract.id
                            }
                }).then(response => {
                finalData.push({serviceContract: cooperation.serviceContract.namespace, serviceProducerDescription: response.data[0].description, serviceProducerHSAId: response.data[0].hsaId});
            });


            });

            console.log(finalData);



        }

    </script>

</body>

3 个答案:

答案 0 :(得分:1)

我不太确定您的具体问题。但是假设您的意思是您有两个端点,则第一个是返回对象数组的端点(我们称其为'getPeopleArray'):

[
 {
    name: "John",
    id: 1
 },
 {
    name: "Anna",
    id: 2
 }
]

,第二个端点返回给定gender的{​​{1}}(让它以一个参数id命名为'getGender'),id将不起作用为你。

您的问题可以通过以下方式解决:

.push

首先是您保存了第一个请求的返回数组,然后您将不得不遍历该数组中的每个对象,以使用let peopleArray = []; axios.get('api/' + 'getPeopleArray').then(people => { peopleArray = people; people.forEach((person, index) => { axios.get('api/' + 'getGender?id='.concat(person.id.toString())) .then(gender => { peopleArray[index].gender = gender; }); }); }); 参数从第二个端点获取并分配它们的genders您的index。只要在所有请求完成期间或之前都没有使用[].forEach(callbackfn)进行操作,索引将是正确的。

更新2: 在评论“为什么.push不起作用?”中回答您的问题时,我决定采用另一种方法,如果您想使用peopleArray结束算法并且不跟踪索引。

.push

通过这种方式,您只有在还提取了对象的性别时,才将对象推到集合let peopleArray = []; axios.get('api/' + 'getPeopleArray').then(people => { people.forEach((person) => { axios.get('api/' + 'getGender?id='.concat(person.id.toString())) .then(gender => { peopleArray.push({id: person.id, name: person.name, gender, gender}); }); }); }); 中。这也将消除不必使用peopleArray(如注释中所建议的那样)仅存储您希望保留的单个对象的属性,因为在行.map上推送了一个新的结构化对象。

答案 1 :(得分:1)

我不喜欢阅读链接的诺言,而是更喜欢使用async/await。您可以先获取列表,然后使用map遍历该列表,然后为每个名称请求性别。请记住,您必须等待所有承诺在map内部解决,然后才能继续。

const axios = require('axios');

async function getPeople() {
    let firstResult = await axios.get('api/path/endpoint1');
    // firstResult = [{name: "John", id: 1}, {name: "Anna", id: 2}]

    let updatedResult = firstResult.map(async item => {
        let people = await axios.get('api/path/endpoint2' + item.name); // or however your endpoint is designed 
        // people = {name: "John", id: 1, gender: male}
        item.gender = people.gender;
        return item; 
    });
    // updatedResult = undefined

    Promise.all(updatedResult)
        .then(finalResult => console.log(finalResult));
    //  [{name: "John", id: 1, gender: male}, {name: "Anna", id: 2, gender: female}]
}

答案 2 :(得分:0)

您可以使用异步/唤醒,然后将gender键重新分配给第一个端点数据...

var users;
axios.get('api/' + endpoint1]).then(response => {
   users = response; // assume all user id list
   for(var idx in users) {
     var data = async () => { return await axios.get('api/' + users[idx].id) } //get gender api by user id
     users[idx].gender = data.gender; //create gender key value 
   }
   console.log(users);
});