【问题标题】:How to wait until a for loop finishes using async await in javascript?如何在 javascript 中使用 async await 等到 for 循环完成?
【发布时间】:2019-02-25 10:36:21
【问题描述】:

我的用例。

  1. 我在浏览器中将 5 张图片上传到 s3 服务器并获取该图片上传的 url。
  2. 将该网址传递给后端。

这是我的异步函数

try{
    await uploadImagesToS3(imagesArray);

    await saveUrlsInBackend();

}catch(error){

}

在我的 uploadImagesToS3 函数中,我正在尝试做这样的事情。

uploadImagesToS3(){
    resolve(FORLOOP)
}

在 for 循环运行 5 次后,我想将其解析为我的主要异步函数。

这是我真正的 uploadImagesToS3 功能

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;
            }
          );
        }
        );
      });
    }

但它不允许我在解析函数中使用 for 循环。 我怎样才能实现这种异步等待机制?

【问题讨论】:

  • 最好使用递归函数而不是循环。所以你可以让它同步。内部函数完成后,就可以解析主函数了。
  • 你知道异步不是非阻塞的吗?它只是延迟了一些代码的执行,但如果该代码需要一段时间,它会在启动时阻塞。

标签: javascript ecmascript-6 async-await


【解决方案1】:

"resolve(FORLOOP)" - 不,这不是它的工作方式。

您应该将s3.upload 方法单独承诺到一个函数中,该函数只调用它并返回结果的承诺而不是其他任何东西:

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

现在你可以在你的方法中使用它,要么将 Promise 链接在一起,要么简单地使用 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;
    }
  }
}

【讨论】:

  • 链接promise或在循环中使用async/await有效地使onUpload同步上传文件列表。您是否有理由建议这样做而不是让上传并行进行?
  • @deefour 这就是大多数人在说“循环”时所想到的,问题中的主要问题是关于承诺和一般语法,所以这就是我所关注的。 (此外,文件上传通常受带宽限制,并行执行可能不一定会使其更快)。当然是one could easily make them concurrent
猜你喜欢
  • 1970-01-01
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 2017-04-29
相关资源
最近更新 更多