How do you make axios GET request wait?

20,707

Solution 1

Option 1: Promise.all

In short: you can use Promise.all() if you need a specific order. You create a an array filled with promises, pass it to Promise.all() and you'll get an array with resolved promises.

const fetch = require("node-fetch");

algo = "eth" // algorithm for wtt
hashrate = ['250', '100', '50']

wttURL = [];

for (var i = 0; i < vhr.length; i++) {
    wttURL.push(fetch("https://whattomine.com/coins.json?" + algo + "=true" + "&factor%5B" + algo + "_hr%5D=" + hashrate[i]))
}

Promise.all(wttURL)
    .then(responses => responses.forEach(response => console.log(response)))
    .catch(err => console.log(err));

However, it fails with the reason of the first promise that rejects. So if you have a big array or you need to display any data you should not use this method. In addition, this would keep the order on the client only! Your backend would not know anything about the order since the calls are not done in order.

Option 2: Async/Await

You could use async/await instead. You would await each result and if any of them fails you do not care since the rest still can succeed. Also, your backend would be able to keep track of the order too.

async function getData() {
    for (var i = 0; i < vhr.length; i++) {
        let wttURL = "https://whattomine.com/coins.json?" + algo + "=true" + "&factor%5B" + algo + "_hr%5D=" + hashrate[i]
        await fetch(wttURL)
                .then(resp => resp.json()) // Transform the data into json
                .then(data => console.log(data.coins.Ethereum.btc_revenue))
                .catch(err => console.log(err));
    }
}

This approach preserves the original order on the client and backend (if you log it). However, it is slower than the first solution since it does not continue with the next fetch until the promise is resolved.

Solution 2

You can use recursion in the next way:

function fetchRecursively(int currentStep, int n) {
    var wttURL = "https://whattomine.com/coins.json?" + algo + "=true" + "&factor%5B" + algo + "_hr%5D=" + hashrate[currentStep]
    fetch(wttURL)
        .then((resp) => resp.json()) // Transform the data into json
        .then(function(data) {
            console.log(data.coins.Ethereum.btc_revenue);
            if (currentStep < n) {
                fetchRecursively(currentStep + 1, n);
            }
        })
}

And replace for loop:

for (var i = 0; i < vhr.length; i++){

var wttURL = "https://whattomine.com/coins.json?" + algo + "=true" + "&factor%5B" + algo + "_hr%5D=" + hashrate[i]



fetch(wttURL)
.then((resp) => resp.json()) // Transform the data into json
.then(function(data) {
  console.log(data.coins.Ethereum.btc_revenue)
  })

with this:

fetchRecursively(0, vhr.length);

Solution 3

Use Promise.all , so as to preserve the order.

In for loop , iam creating three fetch promises and chaining then to get response in json format and pushing them to array.

Finally , i am using Promise.all to get data in prdefined formar

const fetch = require("node-fetch");

algo = "eth" // algorithm for wtt

hashrate = ['250', '100', '50']

console.log(hashrate)

var fetchUrl =[]
for (var i = 0; i < vhr.length; i++){

return fetchUrl.push(fetch("https://whattomine.com/coins.json?" + algo + "=true" + "&factor%5B" + algo + "_hr%5D=" + hashrate[i]).then(response => response.json())
}


Promise.all(fetchUrl)
.then(function(data) {
  data.forEach(a => a.coins.Ethereum.btc_revenue)
  })
Share:
20,707
knitty
Author by

knitty

Updated on March 18, 2022

Comments

  • knitty
    knitty about 2 years

    Hi I'm having a problem with using axios / fetch GET with a URL that has a parameter that iterates through an array loop for its values

    axios / fetch doesn't follow the order of the array and just returns whichever response comes first.

    How would I fix this?

    const fetch = require("node-fetch");
    
    algo = "eth" // algorithm for wtt
    
    hashrate = ['250', '100', '50']
    
    console.log(hashrate)
    
    
    for (var i = 0; i < vhr.length; i++){
    
    var wttURL = "https://whattomine.com/coins.json?" + algo + "=true" + "&factor%5B" + algo + "_hr%5D=" + hashrate[i]
    
    
    
    fetch(wttURL)
    .then((resp) => resp.json()) // Transform the data into json
    .then(function(data) {
      console.log(data.coins.Ethereum.btc_revenue)
      })

    The output for this currently is either the results for 250 (a), 100 (b) or 50 (c)

    So basically it would either come out as

    a, b, c (desired)

    b, c, a

    a, c, b

    c, b, a

    etc.

    But I want it to output according to the order so it should be

    a ,b ,c always

    • Pranay Rana
      Pranay Rana over 5 years
      try rxjs forkjoin function
    • Alberti Buonarroti
      Alberti Buonarroti over 5 years
      It follows the order but not all requests are completed at the same time - that's the basic idea of async operations. They are done whenever they are done. If you need to wait for all resulst use Promise.all
    • Admin
      Admin over 5 years
      @AlbertiBuonarroti turn that into an answer
    • Admin
      Admin over 5 years
      Also note that JS implementations do not always return an array in order of input.
  • Alberti Buonarroti
    Alberti Buonarroti over 5 years
    Cool idea to kinda simulate await if your environment does not support it!