You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用async/await实现ngx-file-drop多图顺序上传并传递post_id参数

多图按顺序上传需求及解决方法

需求背景

  • 使用ngx-file-drop组件实现拖拽多图上传功能
  • 需要通过async/await实现图片按顺序上传,首个请求返回的post_id要作为参数携带在后续所有图片的上传请求中

现存问题

现有实现不会等待上一个上传请求完成就发起下一个请求,无法满足post_id的传递要求,原有实现代码如下:

dropped(files: NgxFileDropEntry[]) {
    this.files = files;
    for (const droppedFile of files) {

      // 判断是否为文件
      if (droppedFile.fileEntry.isFile) {
        const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
        fileEntry.file(async (file: File) => {
          // 此处可获取到真实文件对象
          console.log(droppedFile.relativePath, file);

          await new Promise((resolve, reject) => {
            this.http.uploadImages(file, 'UploadImage', this.postId).subscribe((res: any) => {
              if (res.status == true) {
                resolve(true);
                this.postId = res.data.post_id; // 期望将这个ID传递到下一个请求
              } else {
                reject();
                console.log(res.message);
              }
            })
          });


        });
      } else {
        // 为目录时的逻辑(空目录也会被纳入,否则仅处理文件)
        const fileEntry = droppedFile.fileEntry as FileSystemDirectoryEntry;
        console.log(droppedFile.relativePath, fileEntry);
      }
    }
  }

问题根因

原有代码中fileEntry.file()的回调为异步执行,循环不会等待回调内的Promise完成就会处理下一个文件,因此请求会并发发出,post_id无法按预期顺序传递。

修复后代码

// 先将FileEntry转File的回调逻辑封装为Promise,方便后续await调用
private getFileFromEntry(fileEntry: FileSystemFileEntry): Promise<File> {
  return new Promise((resolve) => {
    fileEntry.file((file) => resolve(file));
  });
}

async dropped(files: NgxFileDropEntry[]) {
  this.files = files;
  // 先筛选出所有需要上传的文件,排除目录项
  const fileEntries = files
    .filter(f => f.fileEntry.isFile)
    .map(f => f.fileEntry as FileSystemFileEntry);

  // 按顺序循环处理每个文件,await等待上一个上传完成后再处理下一个
  for (const entry of fileEntries) {
    const file = await this.getFileFromEntry(entry);
    // 上传逻辑,等待当前上传完成后才会进入下一次循环
    await new Promise((resolve, reject) => {
      this.http.uploadImages(file, 'UploadImage', this.postId).subscribe((res: any) => {
        if (res.status == true) {
          this.postId = res.data.post_id;
          resolve(true);
        } else {
          console.log(res.message);
          reject(res.message);
          // 若出错后需要中断后续上传保留此处reject即可;若需要继续上传可改为resolve,按业务需求调整即可
        }
      });
    });
  }
}

实现说明

  • 提前筛选所有需要上传的文件,避免循环中处理目录逻辑干扰异步执行顺序
  • 把fileEntry.file()的回调逻辑封装为Promise后,就可以在循环中用await等待获取到文件再执行上传
  • for...of循环搭配await会严格按顺序执行,上一个文件上传完成、postId更新后才会处理下一个文件,完全满足需求

内容的提问来源于stack exchange,提问作者Najam Us Saqib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 10:45:03