3

I have array of links like so:

let array = ['https://1','https://2','https://3']

Than i want to loop all elements and run fetch on them. Still fetch is async so i get request more times i deal this problem removing element from array like so:

array.forEach((link,index) => {
    fetch(link, {mode: 'no-cors'}).then(function () {
        //more stuff not inportant
    }).catch(e => {
        console.error('error', e);
    });
    array.splice(index,1)
})

I wonder is there better solution to solve this ?

2
  • 5
    It's not a good practice to mutate an array you iterate. Why do you need this in here? Commented Nov 19, 2018 at 15:27
  • You might want to investigate Promise.all. Commented Nov 19, 2018 at 15:29

3 Answers 3

15

You want to use Promise.all for this, like so:

// store urls to fetch in an array
const urls = [
  'https://dog.ceo/api/breeds/list',
  'https://dog.ceo/api/breeds/image/random'
];

// use map() to perform a fetch and handle the response for each url
Promise.all(urls.map(url =>
  fetch(url)
    .then(checkStatus)                 
    .then(parseJSON)
    .catch(logError)
))
.then(data => {
  // do something with the data
})
Sign up to request clarification or add additional context in comments.

Comments

1

I would use Promise.all() in this instance. Start with getting the body from each response. Then do something with the responses after the respective promises are fulfilled:

let urls = ['https://1','https://2','https://3']

Promise.all(urls.map(url =>
   // do something with this response like parsing to JSON
   fetch(url,{mode: 'no-cors'}).then(response => response)
)).then(data => {
   // do something with the responses data
})

2 Comments

What is that first then for?
@ScottSauyet I guess we could remove that but you might want to parse the data , I'll add a comment to explain thanks
-1

The responses will be coming in order they finish.

const urls = [1,2,3,4];

// using async await with for loop

const der = async (x) => {
    const f = await fetch(`https://jsonplaceholder.typicode.com/todos/${x}`)
    const j = await f.json()
    return j;
};

urls.forEach(async(url) => {console.log(await der(url))});

// using promise all with then method

Promise.all(urls.map(x =>
   fetch(`https://jsonplaceholder.typicode.com/todos/${x}`).then(response => response.json())
)).then(data => {
   console.log(data)
})

2 Comments

The forEach solution is wrong. As stated in the documentation, forEach does not wait for promises. Since ES18, if you want an asynchronous for interation, you should use for await...of.
when brain becomes brain++

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.