【问题标题】:Waiting for all Ajax calls to complete inside for loop then redirect等待所有 Ajax 调用在 for 循环内完成,然后重定向
【发布时间】:2021-09-02 07:45:29
【问题描述】:

我想遍历 files 数组并将每个文件发送到我们的后端(我们使用 D365)。

我有以下代码:

function SaveDocs() {
    $.each(files, function (index, value) {
        var reader = new FileReader();
        reader.onloadend = function (evt) {
            var base64 = reader.result == "data:" ? "" : reader.result.split(',')[1];
            var data = JSON.stringify(...);
            // Create Annotation in D365
            $.ajax({
              url: baseUrl + "CreateAnnotation",
              type: 'POST',
              dataType: 'json',
              data: data,
              contentType: 'application/json'
           });
        };
      reader.readAsDataURL(value);           
    }); // end of for loop
}

上面的函数是通过点击一个按钮来调用的,我想在所有的 Ajax 调用都完成后重定向用户。

我试过用这个:

$('#myBtn').click(function(){
  // files array is already defined and contains data
  SaveDocs();
  Redirect(); // redirects to page where user can view all uploaded files
})

问题出在重定向之后。我只能打开一些文件,而其他文件显示为已损坏。 我怀疑这是因为 reader 内部的 Ajax 调用尚未完成,这就是为什么一些文件正在工作而另一些文件“损坏”的原因。

我还尝试使用async: false 将 Ajax 调用设置为“异步”,但问题仍然存在。 在Redirect 上设置Timeout 也无济于事。

是不是因为reader.onloadend函数本身是异步的?

我该如何解决这个问题?有没有办法让reader.onloadend 同步?我知道这是不好的做法,但我不介意阻止用户,因为我所做的只是将他们重定向到不同的页面。

【问题讨论】:

    标签: jquery ajax filereader


    【解决方案1】:

    我建议“承诺”阅读器,然后使用Promise.all,直到所有文件都上传完毕。

    这是一个示例,可能需要进行一些调整,因为我没有对其进行测试。

    SaveDocs = async (event, files) => {
      const filePromises = files.map((file) => {
        // Return a promise per file
        return new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = async () => {
            try {
              var base64 = reader.result == "data:" ? "" : reader.result.split(',')[1];
              var data = JSON.stringify(...);
              const response = await this.submitFile(data);
              // Resolve the promise with the response value
              resolve(response);
            } catch (err) {
              reject(err);
            }
          };
          reader.onerror = (error) => {
            reject(error);
          };
          reader.readAsDataURL(file);
        });
      });
    
      // Wait for all promises to be resolved
      const fileInfos = await Promise.all(filePromises);
    
      console.log('COMPLETED');
    
      // Profit
      return fileInfos;
    };
    
    async submitFile(data) {
      // Create Annotation in D365
      return $.ajax({
        url: baseUrl + "CreateAnnotation",
        type: 'POST',
        dataType: 'json',
        data: data,
        contentType: 'application/json'
      });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 2014-07-19
      • 2011-04-26
      相关资源
      最近更新 更多