数组中每个值的新API调用

时间:2019-02-11 22:48:14

标签: node.js

我基本上希望得到这种对象:

  

[{id:5040,requester_id:1234,requester_name:'John'},{id:5046,   requester_id:999,requester_name:'Jim'},{id:5049,requester_id:   543,requester_name:'Alex'}]

这是票证的对象,票证具有多个属性。

我正在使用的API有一个调用来接收票证。检索此没有问题。我从此API调用中获得的信息是:

  

[{id:5040,requester_id:1234},{id:5046,requester_id:999},{   id:5049 requester_id:543}]

基于每个requester_id,我需要执行另一个API调用以获取请求者的名称。对于requester_id 1234,它给出了以下信息:

  

{requester_id:1234,名称:“约翰”)

每个请求者都需要自己的API调用才能获取此信息。

如果Nodejs是一种异步编程语言,我会做这样的事情:

var tickets = api({ method: 'get', path: '/tickets' });
for (var i=0; i<tickets.length; i++){
  var contact = api({ method: 'get', path: '/contact/'+tickets[i].requester_id);
  tickets[i].name = contact.name;
}

显然,这不起作用。

我尝试使用回调,promise和其他工具来获取API数据(我现在的偏好是“请求”)。我已经花了8个小时,却无法正常工作。

我需要for循环才能等待第一个API调用完成。然后,我需要循环的每个迭代来等待上一个迭代完成。

我的API函数返回一个这样的Promise:

return new Promise(function(resolve, reject) {
  request.get(options, function(err, resp, body) {
    if (err) {
      reject(err);
    } else {
      resolve(JSON.parse(body));
    }
  });
});

在许多不同的失败尝试中,这是最后一次:

var tickets = [];
var contacts = [];

var insertContactData = function(reqId){
    return api({ method: 'get', path: '/contacts/'+reqId });
}

var main = function(){
  var myTickets = api({ method: 'get', path: '/tickets');
  myTickets.then(function(result) {
               var ticketData = result.results;

               for (var i=0; i < result.results.length; i++){
                 var thisTicket = {};
                 thisTicket.id = ticketData[i].id;
                 tickets[i] = thisTicket;
               }
               var contacts = [];
               for (var i=0; i < result.results.length; i++){
                 var idExists = false;
                 for (var j=0; j < contacts.length; j++){
                   if (contacts[j].requesterId == tickets[i].requesterId){
                     idExists = true;
                   }
                 }
                 if (idExists == false){
                   var newCont = {};
                   newCont.requesterId = tickets[i].requesterId;
                   contacts.push(newCont);
                 }
               }
               contacts.shift();
               for (var i=0; i < contacts.length; i++){
                 var pos = i;
                 var reqId = contacts[i].requesterId;
                 var contact = insertContactData(reqId);
                 
                 console.log(contact);
               }
             }, errHandler).catch(function(error){
               console.log('ERROR '+error);
             });
}

请帮助?

1 个答案:

答案 0 :(得分:0)

如果需要在继续之前等待异步请求,则可以使用async / await

async function loadTicketInfo() { 
  const tickets = await api({ method: 'get', path: '/tickets' });
  for (let i=0; i<tickets.length; i++){
    var contact = await api({ method: 'get', path: '/contact/'+tickets[i].requester_id);
    tickets[i].name = contact.name;
  }
};

尽管这取决于您希望拉出多少张票,但操作可能会很慢。我建议您并行提取所有票证信息,然后在末尾将其汇总起来

const ticketInfos = tickets.map(t => api({ method: 'get', path: '/contact/' + t.requester_id));
const infos = await Promise.all(ticketInfos);
tickets.forEach(t => {
  const info = infos.find(i => i.requester_id === t.requester_id);
  if (info) {
    t.requester_name = t.name;
  }
});