Home > Enterprise >  Chaining promises to a Promise.all doesn't work with nested maps?
Chaining promises to a Promise.all doesn't work with nested maps?

Time:09-23

Originally I had some code that looked like this...

function attachFilesToSelectedItems(file, item, server) {
  try {
    return await Promise.all(
      files.map(file => {
        return items.map(item=> {
          const formData = new FormData();
          formData.append("attachment", file);
          return server.addAttachment(item, formData);
        });
      })
    );
  } catch {
    return _strings.uploadError;
  }
}

But this doesn't seem to work as expected, it doesn't wait for all the server.addAttachment calls to finish.

Changing it around to not use maps and make a new Promise does fix it.

function attachFilesToSelectedItems(file, item, server) {
  const promises = [];
  files.forEach(file => {
    items.forEach(item => {
      const formData = new FormData();
      formData.append("attachment", file);
      promises.push(server.addAttachment(item, formData));
    });
  });
  return Promise.all(promises).catch(() => {
    return _strings.uploadError;
  });
}

Why does the approach to chain map values and using async/await not work?

CodePudding user response:

Why would it wait for a nested array in the first place?

Wrap nested array in Promise.all to create a promise out of it

function attachFilesToSelectedItems(file, item, server) {
  try {
    return await Promise.all(
      files.map(file => {
        return Promise.all(items.map(item=> {
          const formData = new FormData();
          formData.append("attachment", file);
          return server.addAttachment(item, formData);
        }));
      })
    );
  } catch {
    return _strings.uploadError;
  }
}

CodePudding user response:

the result of the first level map doesn't return what you think it does, so in the end it's trying to run Promise.all on an array of arrays of promises, you would have to flatten it:

files.map(file => {
  return items.map(item=> {
    const formData = new FormData();
    formData.append("attachment", file);
      return server.addAttachment(item, formData);
    });
  })

returns [[promise, promise, ...], [promise, promise, ...]]

and Promise.all doesn't know how to handle it

  • Related