0

I'm making a program that takes an array of links and returns how many are broken and how many are working. Right now, I'm testing it with an array that has four working links and two broken links. Here's my code:

function getBrokenLinks(linksArr){
    let links = linksArr
    let brokenLinks = 0
    links.forEach(link => {
        fetch(link.href)
            .then( res => {
                if ( res.status != 200 ){
                    brokenLinks++
                }
            }).then( () => {console.log(brokenLinks)})
    })
    return brokenLinks
} 

and this is the output i receive:

output

I want the console to print the total of broken links only once, and after it has completed fetching all the links.

2 Answers2

1

You need to wait for all promises first. Then you can print the result. Also, to return anything, you need to make the function async and then all your outer code must also be async!

async function getBrokenLinks (linksArr) {
    let brokenLinks = 0
    await Promise.all(linksArr.map(link => (async () => {
      try {
        const res = await fetch(link.href)
        if (res.status != 200) brokenLinks++
      } catch (e) {
        brokenLinks++
      }
    })()))

    console.log(brokenLinks)
    return brokenLinks
} 
CherryDT
  • 13,941
  • 2
  • 31
  • 50
0

You can use Promise.all to wait for all promises to be resvoled:

/*
Promise.all([promise1, promise2,..])
.then(function() {
    // all promises have been resolved
})
*/

function getBrokenLinks(linksArr) {
    let links = linksArr
    let brokenLinks = 0
    let promises = []

    links.forEach(link => {
        // save promise to push onto array
        let promise = fetch(link.href)
        .then(res => {
            if (res.status != 200) {
                brokenLinks++
            }
        })
        promises.push(promise)
    })

    return Promise.all(promises)
    .then(() => {
        return brokenLinks
    })
} 

// Calling code:
/*
getBrokenLinks([])
.then(console.log)
*/
marco-a
  • 4,996
  • 1
  • 15
  • 41