jordan
jordan

Reputation: 63

How can I wait for all promises to resolve before returning all their values?

I'm using Promise.map from bluebird. I'm trying to wait for all promises to resolve before dispatching an event that contains an array of objects.

readFiles() {
    const fileArray = Array.from(this.fileSelectInput.files)
    const promises = []

    window.Promise.map(fileArray, (file, index) => {
      return window.jsmediatags.read(file, {
        onSuccess: tag => {
          promises.push({
            id: index + 1,
            title: tag.tags.title || undefined,
            artist: tag.tags.artist || undefined
          })
          promises.sort((a, b) => a.id - b.id)
          console.log('I should be first')
        }
      })
    }).then(() => {
        console.log('I should be second')
        this.dispatchEvent(new CustomEvent('tracks-selected', {
          detail: promises
        }))
      }
    }

I'm running into the problem where I should be second is printed to the console before I should be first. the detail: promises dispatched by the event contains an empty array.

Upvotes: 0

Views: 133

Answers (1)

Bergi
Bergi

Reputation: 664395

You're probably looking for

const fileArray = Array.from(this.fileSelectInput.files);

window.Promise.map(fileArray, file => {
  return new Promise((resolve, reject) => {
    window.jsmediatags.read(file, {
      onSuccess: resolve,
      // also pass reject as an error handler if jsmediatags supports that
    });
  });
}).then(tags => {
  const results = tags.map(tag => ({
    id: index + 1,
    title: tag.tags.title || undefined,
    artist: tag.tags.artist || undefined
  }));
  // results.sort((a, b) => a.id - b.id) - not necessary given .map() keeps the order
  this.dispatchEvent(new CustomEvent('tracks-selected', {
    detail: results
  }))
});

Upvotes: 1

Related Questions