0

I have a function that takes an array of URLs and downloads them. It looks like this:

const loadFiles = filePaths => {
  return new Promise((resolve, reject) => {
    let fetchPromises = filePaths.map(filePath => fetch(filePath))

    Promise.all(fetchPromises).then(fetchResolves => {
      let textPromises = []
      fetchResolves.forEach(fetchResolve => {
        if (!fetchResolve.ok) {
          return reject(`${fetchResolve.statusText} : ${unescape(fetchResolve.url)}`)
        }

        textPromises.push(fetchResolve.text())
      })
      Promise.all(textPromises).then(resolve)
    })
  })
}

export {loadFiles}

The issue I am having is that the multiple calls to Promise.all start to resemble callbacks even though I am using promises.

Is there a way to map the functionality of Promise.all to async and await to simplify this function?

How do I do this?

Startec
  • 12,496
  • 23
  • 93
  • 160
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! The `Promise.all` calls are not your problem. – Bergi May 04 '20 at 21:32
  • @Bergi - reading this post I do not see a clear example of how to avoid it w/r/t a function such as mine. – Startec May 04 '20 at 21:36
  • Just omit the `return new Promise((resolve, reject) => {` wrapper and do `return Promise.all(textPromises)` (instead of `.then(resolve)`). – Bergi May 05 '20 at 14:52

1 Answers1

3

You can await Promise.all just fine. Example:

async function loadFiles(filePaths) {
    let fetchPromises = filePaths.map(filePath => fetch(filePath))
    let fetchResolves = await Promise.all(fetchPromises)

    let textPromises = []
    fetchResolves.forEach(fetchResolve => {
        if (!fetchResolve.ok) {
            throw new Error(`${fetchResolve.statusText} : ${unescape(fetchResolve.url)}`)
        }

        textPromises.push(fetchResolve.text())
    })

    return Promise.all(textPromises)
}
Federkun
  • 36,084
  • 8
  • 78
  • 90