admin管理员组

文章数量:1397093

I have a situation where I need to loop through an array of URLs and fetch the result, but I need to preserve the order of requests, that is the first request should be "saved" (write to a file) first, and so on. The result from the requests are text files and their content do not have any data that reveals the original URL or order.

I have made a demo below, which fetches dummy JSON data.

let promises = [];
let data = [];
let i = 1;

let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');

const fn = async() => {
  while (i < 5) {
    promises.push(
      fetch('/' + i, {
        mode: 'cors',
        headers: headers
      })
      .then(response => response.json())
      .then(json => {
        data.push(json)
      })
    )
    i++;
  }

  await Promise.all(promises).then(() => {
    console.log(data);
  })
}

fn();

I have a situation where I need to loop through an array of URLs and fetch the result, but I need to preserve the order of requests, that is the first request should be "saved" (write to a file) first, and so on. The result from the requests are text files and their content do not have any data that reveals the original URL or order.

I have made a demo below, which fetches dummy JSON data.

let promises = [];
let data = [];
let i = 1;

let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');

const fn = async() => {
  while (i < 5) {
    promises.push(
      fetch('https://reqres.in/api/users/' + i, {
        mode: 'cors',
        headers: headers
      })
      .then(response => response.json())
      .then(json => {
        data.push(json)
      })
    )
    i++;
  }

  await Promise.all(promises).then(() => {
    console.log(data);
  })
}

fn();

If you test the above code, you can see that the results are in random order (based on id), and since the files in my original code are text files, I can't sort it after fetch.

Share Improve this question edited Mar 12, 2020 at 16:23 ADyson 62.2k16 gold badges78 silver badges92 bronze badges asked Mar 12, 2020 at 16:21 AkshayAkshay 14.4k5 gold badges48 silver badges72 bronze badges 2
  • 1 You should push the results to data in the Promise.all() code. – Barmar Commented Mar 12, 2020 at 16:23
  • Thanks @Barmar got it. – Akshay Commented Mar 12, 2020 at 16:26
Add a ment  | 

2 Answers 2

Reset to default 7

Use the values the promises resolve to. No need to keep a separate data array and manually add the values to it. Promise.all makes sure the values are in the same order as the promises.

let promises = [];
let i = 1;

let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');

const fn = async() => {
  while (i < 5) {
    promises.push(
      fetch('https://reqres.in/api/users/' + i, {
        mode: 'cors',
        headers: headers
      })
      .then(response => response.json())
    )
    i++;
  }

  await Promise.all(promises).then(data => {
    console.log(data);
  })
}

fn();

And since you are in an async function you can just do:

var data = await Promise.all(promises);
console.log(data);

Also, you can call this way by creating an array of urls and then calling Promise.all which maps through those urls and returns a single promise with all responses in an array:

let headers = new Headers({'Content-Type':'application/json','Accept':'application/json'});
let params = { mode: 'cors', headers};

(async function() {  
  // Create an array or urls
  const urls = [...Array(4).keys()].map(i => `https://reqres.in/api/users/${i+1}`);
  const response = await Promise.all(urls.map(url => fetch(url, params)))
  const data = await Promise.all(response.map(res => res.json()))
  console.log(data)
}());

本文标签: javascriptFetch in loopkeep result orderStack Overflow