循环上传问题?

想循环上传每个文件,循环第一次时isrepeat参数为true,拿到第一次循环上传成功后台返回的路径,作为往下循环的pathList,并且往下循环isrepeat参数为false,思路有点凌乱乱...

upload(data,action) {
      let formData = new FormData()
      data.forEach((item) => {
        formData.append('fileList', item)
        if (data.length === 1 || action === 'fileUpload') {
          //单文件
          formData.append('pathList', item.name)
        } else {
          formData.append('pathList', item.webkitRelativePath)
        }
        formData.append('pid', this.currentNodeKey)
        formData.append('isrepeat', true)
        this.$myHttp({
          method: 'post',
          url: this.prefix + '/doc/docDir/uploadHtml2Public',
          data: formData,
          headers: { 'Authorization': 'Sys ' + sessionStorage.getItem('token'), 'showLoading': 'true' }
        }).then((res) => {
          this.refreshTree()
        }).catch((error) => {
          console.log(error)
        })
        })
      
    }
阅读 1.1k
avatarAI BotBETA

首先,从你的代码中可以看到,你正在使用循环来上传文件,并且在每次上传时,你都在 formData 对象中添加了新的参数。然后,你使用 this.$myHttp 方法发送一个 POST 请求。

然而,你的代码中存在一些问题。在每次循环中,你都创建了一个新的 formData 对象,这会导致每次循环都发送一个新的 POST 请求,而不是按照你的预期那样,一次循环发送一个文件。

另外,你在每次循环中都添加了 isrepeat 参数,这可能不是你想要的。你可能只想在第一次循环时设置 isrepeattrue,然后在后续的循环中将其设置为 false

以下是一个可能的解决方案:

upload(data, action) {
  let formData = new FormData();
  let isrepeat = true; // 初始化 isrepeat 为 true

  data.forEach((item, index) => {
    formData.append('fileList', item);
    if (data.length === 1 || action === 'fileUpload') {
      formData.append('pathList', item.name);
    } else {
      formData.append('pathList', item.webkitRelativePath);
    }
    formData.append('pid', this.currentNodeKey);
    formData.append('isrepeat', isrepeat); // 根据索引设置 isrepeat 的值

    this.$myHttp({
      method: 'post',
      url: this.prefix + '/doc/docDir/uploadHtml2Public',
      data: formData,
      headers: { 
        'Authorization': 'Sys ' + sessionStorage.getItem('token'), 
        'showLoading': 'true' 
      }
    }).then((res) => {
      if (index === data.length - 1) { // 如果是最后一次循环,刷新树状结构
        this.refreshTree();
      }
    }).catch((error) => {
      console.log(error);
    });

    isrepeat = false; // 在每次循环的末尾将 isrepeat 设置为 false
  });
}

在这个修改后的代码中,我保留了 isrepeat 参数的逻辑,并在每次循环的末尾将其设置为 false。同时,我也添加了一个检查,以确保在处理完所有文件后刷新树状结构。这样就可以解决你的问题。

2 个回答

代码没看明白,不过感觉本质上是一个根据当前请求的响应决定下次如何请求的问题,你看看下面的实例代码有帮助不

const items = [1, 2, 3];
const upload = (file) =>
  new Promise((resolve) => {
    setTimeout(() => {
      const data = items.pop();
      resolve(data);
    }, 1000);
  });

const request = async () => {
  const res = await upload();

  // 替换成你的业务判断
  if (res > 0) {
    console.log('res', res);
    request();
  }
};

request();

第 1 个问题,FormData 每次使用完没有清理

精简一下代码逻辑,大概是这样:

upload(data, action) {
    let formData = new FormData();
    data.forEach((item) => {
        formData.append("fileList", item);
        // 配置 formData
        // 在 myHttp() 中使用 formData
        // 但是,使用后没有清空,所以后面再进循环体的时候,会在之前的数据上添加
    });
}

所以,每次循环体都应该 new FormData()→配置→使用→抛弃,即

upload(data, action) {
    data.forEach((item) => {
        const formData = new FormData();
        formData.append("fileList", item);
        // 配置 formData
        // 在 myHttp() 中使用 formData
        // 因为是局部域内产生的 formData,出了这个作用域就会丢弃
    });
}

第 2 个问题,并非 one by one

myHttp 是一个异步处理过程,调用之后会立即执行下一条语句(与 .then 回调无关),并不会等异步结束。所以整个 forEach 应该会很快执行完成,然后多次文件上传基本上是同时在进行,而不是一个一个的在上传。如果要一个个上传,需要等每次异步结束,最好结合 await 使用 for 语句(forEach 方法不能实现异步等待)。示例:

async upload(data, action) {
  for (const item of data) {
    const formData = new FormData();
    // 配置 formData
    try {
      await this.$myHttp(...);
      this.refreshTree();
    } catch (err) {
      console.log("Error", err);
    }
  }
}

最后一个问题,refreshTree

真的是每上传一个文件就要 refreshTree 吗?是不是应该在循环完成之后再 refreshTree?这个不存在谁对谁错的问题,关键是业务需要是什么,以及 refreshTree 是否会对 data 造成影响,破坏迭代过程。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏