javascript - 仅在 Javascript forEach/map 之后执行代码

标签 javascript foreach async-await

我有一个 forEach 函数,它循环遍历一组文件,将文件上传到 Firebase 存储,然后在上传之后,它将图像引用链接存储到之前定义的数组中。

每次迭代的过程:

  • 获取文件对象并转换为 Blob
  • 将 Blob 上传到 Firebase
  • Blob 上传后,接收回调,其中包含上传的图像引用
  • 将图像引用存储在列表中

forEach 之后,我使用图像引用列表进行进一步处理。 但是,当我尝试引用该列表时,它通常是空的,因为此代码在任何图像上传之前执行(并且未收到引用)。我如何将 async/await 与 Javascript forEach 函数结合使用,在其中我可以调用我的代码以等待它应该期望填充的图像引用列表。我已经尝试在 stackoverflow 上找到解决方案,但对我的解决方案没有帮助。

submitPost = async event => {

event.preventDefault();
const img_names = [];

this.state.files.forEach((ref_, index) => {
  ref_.current.getCroppedCanvas().toBlob(blob => {

    var uploadTask = this.storageRef
      .child("images/" + String(index))
      .put(blob);

    uploadTask.on(
      "state_changed",
      snapshot => {
        var progress =
          (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log("Upload is " + progress + "% done");
      },
      error => {
        console.log(error);
      },
      () => {
        img_names.push(uploadTask.snapshot.ref.toString());
      }
    );
  });
console.log(img_names) // empty here
});

最佳答案

您可以使用 map 而不是 forEach 来实现该功能。将您的数组转换为 promise 数组。然后在 Promise.all() 中使用该数组并等待它。

const promisifyUpload = (storageRef, ref_, index) => {
  return new Promise((resolve, reject) => {
    ref_.current.getCroppedCanvas().toBlob(blob => {

      var uploadTask = storageRef
        .child("images/" + String(index))
        .put(blob);

      uploadTask.on(
        "state_changed",
        snapshot => {
          var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
          console.log("Upload is " + progress + "% done");
        },
        error => console.log(error),
        () => resolve(uploadTask.snapshot.ref.toString())
      );

    });
  });

};

const submitPost = async event => {

  event.preventDefault();

  const img_names = await Promise.all(
    this.state.files.map((ref_, index) => promisifyUpload(this.storageRef, ref_, index))
  ));

  console.log(image_names); // Should now be filled
});

编辑:我将它分成 2 个函数以显示隔离“promisify”逻辑

关于javascript - 仅在 Javascript forEach/map 之后执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59057613/

相关文章:

javascript - 将 Sequelize promise 嵌入到 javascript async/await 链中

javascript - UI Angular Bootstrap typeahead 隐藏第一个选项

javascript - 如何将事件监听器添加到我的 javascript 函数

node.js - 运行 Mocha 测试时出现 node-mssql "connection is closed",但在应用程序中运行良好

c# - 嵌套异步与 Entity Framework

php - 无法加载请求的文件: templates/header. php

javascript - 如何在 yii2 中使用 php jquery?

javascript - HTML5和JS将多个图像拖放到特定位置

javascript - JS/Jquery - 如果输入有任何数组名称,则返回关联值

javascript - 在另一个 ForEach 中创建一个 forEach