2

My use case.

  1. I upload 5 images to the s3 server in the browser and get that images uploaded urls.
  2. Pass that urls to the back-end.

This is my async function

try{
    await uploadImagesToS3(imagesArray);

    await saveUrlsInBackend();

}catch(error){

}

In my uploadImagesToS3 function I'm trying to do something like this.

uploadImagesToS3(){
    resolve(FORLOOP)
}

After for loop run 5 times I want to resolve it to the my main async function.

This my real uploadImagesToS3 function

onUpload(array, albumName) {
      return new Promise((resolve, reject) => {
        resolve(
          for (let index = 0; index < array.length; index++) {
          var files = document.getElementById(array[index]).files;
          if (!files.length) {
            return alert("Please choose a file to upload first.");
          }
          var file = files[0];
          var fileName = file.name;
          var albumPhotosKey = encodeURIComponent(albumName) + "//";

          var photoKey = albumPhotosKey + fileName;
          self;
          s3.upload(
            {
              Key: photoKey,
              Body: file,
              ACL: "public-read"
            },
            (err, data) => {
              if (err) {
                return alert(
                  "There was an error uploading your photo: ",
                  err.message
                );
              }
              // alert("Successfully uploaded photo.");
              this.images[index].image_path = data.Location;
            }
          );
        }
        );
      });
    }

But it doesn't let me to use a for loop inside a resolve function. How could I achieve this async await mechanisms?

Kols
  • 3,641
  • 2
  • 34
  • 42
margherita pizza
  • 6,623
  • 23
  • 84
  • 152
  • 1
    better use recursive function instead of loop. so you can make it sync. once the internal function completed then you can resolve main function. – Arif Rathod Sep 21 '18 at 04:34
  • Did you know async isn’t non-blocking? It just delays the execution of some code, but if that code takes a while, it will block when it starts. – evolutionxbox Sep 21 '18 at 07:03

1 Answers1

2

"resolve(FORLOOP)" - no, that's not how it would work.

You should promisify the s3.upload method alone, into a function that just calls it and returns a promise for the result and nothing else:

function upload(value) {
  return new Promise((resolve, reject) => {
    s3.upload(value, (err, res) => {
      if (err) reject(err);
      else resolve(res);
    });
  });
}

Now you can use that in your method, either by chaining the promises together or by simply using async/await:

async onUpload(array, albumName) { /*
^^^^^ */
  for (const id of array) {
    const files = document.getElementById(id).files;
    if (!files.length) {
      alert("Please choose a file to upload first.");
      return;
    }
    const file = files[0];
    const albumPhotosKey = encodeURIComponent(albumName) + "//";

    const photoKey = albumPhotosKey + file.name;
    try {
      const data = await upload({
//                 ^^^^^
        Key: photoKey,
        Body: file,
        ACL: "public-read"
      });
      // alert("Successfully uploaded photo.");
      this.images[index].image_path = data.Location;
    } catch(err) {
      alert("There was an error uploading your photo: ", err.message);
      return;
    }
  }
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Chaining the promises or using async/await in the loop here effectively makes `onUpload` upload the list of files synchronously. Is there a reason you are suggesting this vs letting the uploads occur in parallel? – deefour Sep 24 '18 at 17:53
  • @deefour That's what most people think of when they say "loop", and the major issue in the question was about promises and syntax in general so that's what I was focusing on. (Also file uploads are often limited by bandwidth, doing it in parallel might not necessarily make it perceivably faster). Of course [one could easily make them concurrent](https://stackoverflow.com/a/37576787/1048572). – Bergi Sep 24 '18 at 18:40