循环异步调取接口使用数组promiseList保存,Promise.all(promiseList)获取不到数组内容,then()返回空数组

在使用 vue + [email protected] 技术栈的项目中,因为上传文件的接口是单文件上传,当使用批量上传时,只能循环调取接口;然后有校验内容:需要所有文件上传成功后才能保存,在文件上传不成功时点击保存按钮,则提示信息:"文件上传未成功!"

我使用 for 循环调取接口,然后定义了 promiseList 数组,循环一次将 promise 对象添加一次,然后使用 Promise.all(promiseList).then(result=>console.log(result)) 来改变保存的状态。但是发现打印出的 result 总是空数组[]。debugger 代码的执行顺序,应该是异步的原因导致的。

如下代码:

/** 上传文件组件 */
<van-uploader
  name="multipartFile"
  multiple
  v-model="jobFileList"
  :after-read="(file) => afterRead(file, jobFileList)"
  :before-read="(file) => beforeRead(file, jobFileList)"
  :before-delete="(file) => beforeDelete(file, jobFileList)"
  :max-count="9"
>
</van-uploader>

下面上传了一张图片文件格式;如下图,其中 fileId、fileName、fileType、fileUrl 为自定义字段,上传服务器成功后返回的,其他字段为 van-uploader 组件所支持的自有字段。
循环异步调取接口使用数组promiseList保存,Promise.all(promiseList)获取不到数组内容,then()返回空数组_第1张图片

/** 上传文件逻辑 */
afterRead(file, jobFileList) {
  console.log("file", file); // 如上图
  const _this = this;
  this.isFetchDone = 1; // 文件是否全部上传完成:0是 1否
  let promiseList = [];
  for (const f of file) {
  	// 压缩文件
    new Compressor(f.file, {
      quality: 0.5,
      success(result) {
        // blob格式转换为file格式
        f.file= new File([result], result.name, { type: result.type });
        const p = _this.uploadFileChange(f, jobFileList);
        promiseList.push(p);
      },
      error(err) {
        console.warn(err.message);
      },
    });
  }
  // 使用Promise.all()改变保存状态
  Promise.all(promiseList).then(result=> {
    console.log(result);  // []
    // 所有的文件状态都是"done"则代表文件全部上传完成 
    const bool = result.every(file => file.status === 'done');
     if (bool) {
       // 改变保存状态为0,可保存
       this.isFetchDone = 0;
     }
   })
}
/** 上传文件逻辑 */
uploadFileChange(f, jobFileList) {
  return new Promise((resolve, reject) => {
    f.status = "uploading";
    f.message = "上传中...";
    // 上传图片要formData类型
    const formData = new FormData();
    formData.append("multipartFile", f.file);
    // 上传文件接口
    uploadFile(formData).then((response) => {
      const { data, resultCode } = response;
      if (resultCode === 0) {
        f.status = "done";
        f.message = "上传完成";
        resolve(f);
      } else {
        f.status = "failed";
        f.message = "上传失败";
        reject(f);
      }
    }).catch(err => {
      f.status = "failed";
      f.message = "上传失败";
      reject(err)
    });
  })
},

上面代码的执行顺序是,先执行 for 循环,然后直接执行了 Promise.all(),最后执行 promiseList.push();因为 forPromise.all()都是同步代码,所以在 Promise.all(promiseList) 执行时,promiseList 其实是一个空数组,所以 then 最终返回的是一个空数组。

我选择的修改方式是将 for 循环放到了 Promise.all() 中,如下:

afterRead(file, jobFileList) {
  const _this = this;
  this.isFetchDone = 1;
  let promiseList = [];
  if (!Array.isArray(file)) {
    promiseList = [file];
  } else {
    promiseList = file;
  }
  /** 可以将 promiseList.map 单独封装成一个函数放在这里(优化代码) */
  Promise.all(
    promiseList.map(f => {
      return new Promise((resolve, reject) => {
        // 压缩文件
        new Compressor(f.file, {
          quality: 0.5,
          success(result) {
            // blob格式转换为file格式
            f.file= new File([result], result.name, { type: result.type });
            f.status = "uploading";
            f.message = "上传中...";
            // 上传图片要formData类型
            const formData = new FormData();
            formData.append("multipartFile", f.file);
            // 上传文件接口
            uploadFile(formData).then((response) => {
              const { data, resultCode } = response;
              if (resultCode === 0 && data) {
                f.status = "done";
                f.message = "上传完成";
                resolve(f);
              } else {
                f.status = "failed";
                f.message = "上传失败";
                reject(f);
              }
            }).catch(err => {
              f.status = "failed";
              f.message = "上传失败";
              reject(err);
            })
          },
          error(err) {
            console.warn(err.message);
          },
        });
      })
    })
  ).then(result => {
    const bool= result.every(file => file.status === 'done');
    if (bool) {
      this.isFetchDone = 0;
    }
  })
},

你可能感兴趣的:(#,JavaScript,javascript,promise.all,promise,图片文件上传)