how to concatenate an object into asynchronous function?

Asked

Viewed 109 times

2

Hello I am developing a site to train a little js, but I came across the following situation: I have a javascript object that I created to facilitate the Ajax queries, but when I am making the requests sometimes a link is solved or terminated(I don’t know the right technical terminology) before the other one, so this keeps my site sometimes not showing the values I want (I’m using the push array method per hour),then I thought about creating a new Object while making the requests with the name of each item, to take the values more easily and have no problems regarding the speed of the resolution of links, but when I perform my function only returns the value of the last name of the created object.

to better illustrate:

Object:

ExchangeInfo = {
  mercadobitcoin:{
    name:"mercadobitcoin",
    bch:{
      orderbook:"https://www.mercadobitcoin.net/api/BCH/orderbook/"
    }
  },
  braziliex:{
    name:"braziliex",
    bch:{
      orderbook:"https://braziliex.com/api/v1/public/orderbook/bch_brl"
    }
  },
  negociecoins:{
    name:"negociecoins",
    bch:{
      orderbook:"https://broker.negociecoins.com.br/api/v3/bchbrl/orderbook"
    }
  }
};

Function:

v = {};
function getApiLinks() {
  for (prop in ExchangeInfo){
    var xml = new XMLHttpRequest();
    xml.open("GET",ExchangeInfo[prop]["bch"]["orderbook"],true);
    xml.send();
    xml.onreadystatechange = function(){
      if(this.status == 200 && this.readyState == 4){
        myObj = JSON.parse(this.responseText);
        v[ExchangeInfo[prop]["name"]]=this.responseText;
        return v[ExchangeInfo[prop]["name"]] = myObj; // resolução parcial que só retorna o ultimo valor consultado exemplo abaixo.
        // return v.push(myObj); resolução atual intermitente
      }
    }
  }
}

returned object:

{
  negociecoins:{
    ask[
      //dados retornados pelo ajax
    ],
    bid:[
      //dados retornados pelo ajax
    ]
  }
}

Expected object:

{
  mercadobitcoin:{
    ask[
      //dados retornados pelo ajax
    ],
    bid:[
      //dados retornados pelo ajax
    ]
  },
  braziliex:{
    ask[
      //dados retornados pelo ajax
    ],
    bid:[
      //dados retornados pelo ajax
    ]
  },
  negociecoins:{
    ask[
      //dados retornados pelo ajax
    ],
    bid:[
      //dados retornados pelo ajax
    ]
  }
}

Sorry if the question got too long, I tried to give as much information as possible.

1 answer

1


There’s no way to do it this way because the for is asynchronous to Ajax and will return the last processing inside it.

The return used will also return undefined because the for will end before the first (total of 3) Ajax request is processed, exactly for being asynchronous.

To get the desired result, you would have to do this synchronously by calling each Ajax request at a time without using the loop for to make requests. You can do it using a function as an example below:

v = {};
function getApiLinks() {
   var array = []; // array para guardar os nomes dos objetos
   for (prop in ExchangeInfo){
      // adicionar os nomes dos objetos para usar no Ajax
      array.push(ExchangeInfo[prop]["name"]);
   }
   // variável que irá contar quantas vezes
   // a função será chamada
   var conta = 0;

   function Ajax(){
      var xml = new XMLHttpRequest();
      xml.open("GET",ExchangeInfo[array[conta]]["bch"]["orderbook"],true);
      xml.send();
      xml.onreadystatechange = function(){
         if(this.status == 200 && this.readyState == 4){
            myObj = JSON.parse(this.responseText);
            //v[ExchangeInfo[prop]["name"]]=this.responseText;
            v[array[conta]] = myObj; // resolução parcial que só retorna o ultimo valor consultado exemplo abaixo.
            // return v.push(myObj); resolução atual intermitente
            conta++;
            // chama novamente a função
            // até que "conta" seja menor que
            // o númrero de itens na array
            if(conta < array.length) Ajax();
         }
      }
   }
   Ajax(); // chama a função

  return v; // retorna o objeto
}

console.log(getApiLinks());

The return v; will return:

braziliex:
{asks: Array(203), bids: Array(32)}

mercadobitcoin:
{asks: Array(1000), bids: Array(247)}

negociecoins:
{ask: Array(162), bid: Array(51)}
  • Thanks for the answer, it worked fine, I didn’t know I couldn’t do with asynchronous requests because it was working with the array, but not with object. was even worth reply.

  • I just didn’t mark the answer with useful before, because my score was too low.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.