Promise.All不等待承诺

时间:2019-09-13 11:52:01

标签: javascript promise

我正在尝试将文件数组上传到s3存储桶。我正在为每个文件构建一个Promise数组,该数组将生成预签名的URL,将文件blob,然后进行上传。上传完成后,每个承诺都应解决。

所有上传完成后,我尝试刷新页面。

我正在尝试使用以下代码进行此操作:

async function uploadFiles() {
  let requestArray = files.map(file => {
    return new Promise(resolve => {
      handleDocs.GenerateUrl(file.fileName, "{!OppName}", async (result, event) => {
        let preSignedUrl = result.Data.toString().replace(/amp;/gm, "");
        let blob = b64toBlob(file.fileString, result.ContentType);

        await fetch(preSignedUrl, {
          method: "PUT",
          body: blob,
          headers: {
            "Content-Type": result.ContentType,
          },
        });

        resolve();
      });
    });
  });

  await Promise.all(requestArray);
  document.location.reload();
}

我的猜测是handleDocs.GenerateUrl的行为方式我无法理解(这是对实际上生成预签名URL的后端Salesforce / APEX服务的调用),诺言不正确。

我找不到能够解决类似问题且对我有用的示例。

实际的逻辑似乎很好,因为文件在大多数情况下确实可以成功上传。我如何建立承诺有任何问题?

任何帮助将不胜感激!

我意识到有关此问题已经存在,但潜在的问题似乎有所不同。

3 个答案:

答案 0 :(得分:0)

我不确定确切的问题是什么,但是可能使事情更容易理解的是使URL生成变得容易:

function generateUrlP(file) {
  return new Promise(resolve =>
    handleDocs.GenerateUrl(
      file.fileName,
      "{!OppName}",
      (result, event) => resolve(result),
    ),
  );
}

async function uploadFiles() {
  const requestArray = files.map(async file => {
    const result = await generateUrlP(file);
    const preSignedUrl = result.Data.toString().replace(/amp;/gm, "");
    const blob = b64toBlob(file.fileString, result.ContentType);
    return fetch(preSignedUrl, {
      method: "PUT",
      body: blob,
      headers: {
        "Content-Type": result.ContentType,
      },
    });
  });

  await Promise.all(requestArray);
  document.location.reload();
}

答案 1 :(得分:0)

您的问题几乎可以肯定是由数组中的一个promise失败引起的。

尝试一下:

async function uploadFiles() {
  // an async function is a function that returns a promise
  let requestArray = files.map(async (file) => { 
    try {
      handleDocs.GenerateUrl(file.fileName, "{!OppName}", async (result, event) => {
        try {
          let preSignedUrl = result.Data.toString().replace(/amp;/gm, "");
          let blob = b64toBlob(file.fileString, result.ContentType);

          await fetch(preSignedUrl, {
            method: "PUT",
            body: blob,
            headers: {
              "Content-Type": result.ContentType,
            },
          });
        } catch(e){
          console.log(`Error in handleDocs`, e)
        }
      });

    } catch (e){
      console.log(`Error in requestArray`, e);
    }
  });
  await Promise.all(requestArray);
};


document.location.reload();

答案 2 :(得分:0)

我想我已经找到了原因和解决方案;我只是误解了诺言的事。

事实证明,这是由我们正在处理的页面上的其他一些问题引起的。

我们拥有的部分功能是能够从S3中删除文档,这可以通过调用我们编写的API来完成。

作为测试的一部分,我们将上传文件,将其删除,然后重新上传,这是我们将看到此问题的时候。

事实证明,aggregate在页面重新加载过程中正在重新提交删除数据。将其更改为document.location.reload();可解决我们遇到的问题。诺言的处理方式似乎没有什么错,所以对误导性问题表示歉意。

感谢您的帮助!