3

I am fetching multiple route using for loop and saving its result this is my code

 for (let i = 0; i < datesToFetch.length; i++) {


fetch("http://localhost:3000/areaChart/"+datesToFetch[i]+"/"+datesToFetch[i+1])
.then(response => response.json())
.then(response => console.log(response))

}

whats really weird that order of data that I am getting is coming random order it is not coming according to for loop ascending order which is really important in this case

what should I do so I get data in proper order ?

2
  • You're getting a random order because the sources take different amount of time to load and deliver. You either can can save the response in an Array and then sort it, when all is loaded or use promises or whatever... hard to tell without knowing what you fetch. Commented Nov 6, 2018 at 15:00
  • 1
    You should have a look at Promise.all, this would help you with that task Commented Nov 6, 2018 at 15:00

4 Answers 4

3

What's going on, and how to fix it:

Your code is queueing up a bunch of fetches, but not waiting for them to finish before moving on to the next iteration of the loop. They can finish in any order.

If instead you wanted the loop to stop and wait each time, wrap it in an async function, and await the fetch.

async function test() {

    for (let i = 0; i < datesToFetch.length; i++) {
        var response = await fetch("http://localhost:3000/areaChart/"+datesToFetch[i]+"/"+datesToFetch[i+1]);
        var responseJson = await response.json();
        console.log(responseJson);
    }

}

A simulation of your code:

const delay = t => new Promise(resolve => setTimeout(resolve, t));

async function test() {
  for (let i = 1; i <= 5; i++) {
    console.log(`Starting call #${i}`);
    delay(5000 - (i * 1000))
      .then(() => console.log(`Call #${i} has completed.`));
  }
}

test();

A simulation of the solution provided above:

const delay = t => new Promise(resolve => setTimeout(resolve, t));

async function test() {
  for (let i = 1; i <= 5; i++) {
    console.log(`Starting call #${i}`);
    await delay(5000 - (i * 1000));
    console.log(`Call #${i} has completed.`);
  }
}

test();

Sign up to request clarification or add additional context in comments.

Comments

2

Welcome to asynchronous code!

One thing you can do is create an empty array that is datesToFetch.length long, and assign the value of response.json() to the appropriate index.

const responses = [...Array(datesToFetch.length)]

for (let i = 0; i < datesToFetch.length; i++) {
  fetch("http://localhost:3000/areaChart/"+datesToFetch[i]+"/"+datesToFetch[i])
    .then(response => response.json())
    .then(response => responses[i] = response)
}

Comments

2

Your case :

You are calling multiple functions that have different resolution time. It's like behing at mcDonald in different queues, some gyus arrived at the same time as you could get his meal before or after yourself.

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

function display(i) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(i);
    }, getRandomInt(1500));
  });
}

for (let i = 0; i < 5; i += 1) {
  display(i)
    .then(x => console.log('->', x));
}


One soluce :

We are using a function called Promise.all to wait for all people to get theirs meals, and then go out of the shop.

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

function display(i) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(i);
    }, getRandomInt(1500));
  });
}

const promises = [];

for (let i = 0; i < 5; i += 1) {
  promises.push(display(i));
}

// We use Promise.all to wait for all responses
// The responses are in the call order
Promise.all(promises)
  .then((rets) => {
      rets.forEach(x => console.log('->', x));
  });

2 Comments

What is the purpose of adding the getRandomInt function?
@Jim It's just an example async function like fetch, but actually works in the snippet
1

That's because this fetch call will be added to the JavaScript event loop. The first one which gives back result will be displayed, so the order can be different then the order in which they are called.

To fix this you should take a look at the await operator. More info can be found here: https://dev.to/johnpaulada/synchronous-fetch-with-asyncawait

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.