How to stop foreach loop when fetch is failed?

Viewed 40

I have a function:

function check(id) {
    let index = 0
    fetch('https://ddragon.leagueoflegends.com/api/versions.json')
    .then(e => e.json())
    .then((res) =>res.forEach( element =>{
        fetch('https://ddragon.leagueoflegends.com/cdn/'+element+'/img/profileicon/'+id+'.png')
        .then(response => {
            if(response.ok){
                index++
            }
            else{
                return index
            }
        })
    }))
}

The code seems to be dirty and not right, sorry for that.

I am getting an array of numbers and at line 6, I check if the website is legit. After some index, invalid URLs will start. I want to break foreach loop when an invalid URL tried to fetch. I tried to convert 'foreach' loop to a 'some' loop and tried some try-catch blocks but I couldn't break the loop. If you want to see how it stacks when invalid URLs start to stack

1 Answers

If you want to count how many requests were fulfilled/rejected you may find Promise.allSettled useful. Add your endpoints to an array, map over the array to create an array of promises, and then await all the promises to resolve/reject. You can then inspect the result to see how many requests have a status that is either "fulfilled" or "rejected".

const arr = [
  'https://jsonplaceholder.typicode.com/todos/1',
  'https://jsonplaceholder.typicode.com/todos/2',
  'https://madeup.url.com/todos',
  'https://jsonplaceholder.typicode.com/todos/4',
  'https://jsonplaceholder.typicode.com/todos/4'
];

// `map` over the array of endpoints and
// return an array of promises
function getPromises(arr) {
 return arr.map(url => {
    return fetch(url)
      .then(res => {
        if (res.ok) return res.json();
      })
      .catch(err => {
        return Promise.reject('Request failed');
      });
  });
}

// Return the count of objects
// with a particular status
function count(data, status) {
  return data.filter(obj => obj.status === status).length;
}

// Create an array of promises, `await` the result, and
// then find out how many were "fulfilled" or "rejected
async function main(arr) {
  const promises = getPromises(arr);
  const data = await Promise.allSettled(promises);
  const fulfilled = count(data, 'fulfilled');
  const rejected = count(data, 'rejected');
  console.log(`Fulfilled: ${fulfilled}\nRejected: ${rejected}`);
}

main(arr);

Related