axios切片上传怎么才能实现同步上传,下一片上传文件需要根据上一片的返回状态码,再决定是否上传?

发布于 2022-09-12 23:59:19 字数 2109 浏览 16 评论 0

我需要怎么把以下的代码,改成问题中的需求呢?

forEach和async和await在一起不能实现同步,

不太懂前端,,很抓狂,求大神仔细讲解

这是在开始上传文件之前,需要先获取文件的在服务器的中状态信息,查看是否已经上传过。

{iCode: 0, strMessage: "Success",…}
iCode: 0
objData: [
{iFileId: 0, strFileName: "1_1000080.zyp", lSize: 101053451, strFileType: "zyp",…}]
0: {iFileId: 0, strFileName: "1_1000080.zyp", lSize: 101053451, strFileType: "zyp",…}
iFileId: 0
lSize: 101053451
listFileSliceInfo: [{lSize: 101053451, strFilePath: "", strStatus: "complete", lProgress: 0}]
0: {lSize: 101053451, strFilePath: "", strStatus: "complete", lProgress: 0}
lProgress: 0
lSize: 101053451
strFilePath: ""
strStatus: "complete"
strFileName: "1_1000080.zyp"
strFileType: "zyp"
strMessage: "Success"
  emitHandle() {
      //上传文件
      let iUpdadeState = 0;
      this.testFilesStatus.forEach((item, index) => {
        let obj = item[0].listFileSliceInfo[0];
        if (obj.strStatus == "none") {
          iUpdadeState = 0;
        } else {
          iUpdadeState = 1;
        }
        let lSize = this.testFiles[index].file.size;
        const sectionSize = 1 * 1024 * 1024;
        const sectionTotal = Math.ceil(lSize / sectionSize);
        for (let i = 0; i < sectionTotal; i++) {
          const startSize = i * sectionSize; // 切片开始位置
          const endSize =
            i === sectionTotal - 1 ? lSize : (i + 1) * sectionSize;
          let fileData = this.testFiles[index].file.slice(startSize, endSize);
          if (this.progress) {
            let formData = new FormData();
            formData.append("file", fileData);
            formData.append("iUpdadeState", iUpdadeState);
            formData.append("iSlideDocumentId", item[0].iFileId);
            formData.append("strFilePath", "");
            FileUploadHandler(formData, (spreed) => {
              // 总大小
              let loaded = 0;
              loaded += spreed.loaded;
              let sep =
(((loaded / this.testFiles[index].file.total) * 100) | 0) +"%";
              this.testFiles[index].file.status = sep;
            });
          }
        }
      });
    },

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流星番茄 2022-09-19 23:59:19

把上传单个分片文件写成一个递归函数。

古镇旧梦 2022-09-19 23:59:19

forEach自然是不可以的,因为它不会受回调函数返回值的影响,可以用 for...in 或者 for...of
之前回答了一个问题,提供了一个异步队列的方案:

function queueGen(processor){
    const taskQueue = [];
    let pendingFlag = false;
    
    async function handler([param, callback, errorHandler]){
        try{
            callback(await processor(param));
        } catch(err) {
            if(errorHandler){
                errorHandler(err)
            }
        }
        consumer();
    }
    
    function consumer(){
        if(!taskQueue.length){
            pendingFlag = false;
            return
        }
        handler(taskQueue.shift());
    }
    
    return function addTask(callback, param, errorHandler){
        taskQueue.push([param, callback, errorHandler]);
        if(!pendingFlag) {
            pendingFlag = true;
            consumer();
        }
    }
}

如果不考虑传输失败的问题的话,放到这里是可以直接用的:

// 假设这个 upload 里的回调函数就是 Promise 化的上传函数
const upload = queueGen(function asyncTimeOut(delay = 1e3){
    return new Promise(function(resolve, reject){
        setTimeout(resolve, delay)
        // 成功的时候执行 resolve
        // 失败的时候执行 reject
    });
});

// 直接按顺序 upload 就可以了,使用 forEach 也无妨
for(let i = 0;i< 10; i++){
    const delay = (10 % i) * 1e3
    upload(() => console.log(`第${i + 1}个任务,延迟了${delay}毫秒`), delay);
}

如果需要考虑失败重试的话需要递归实现,这个方案也可以使用,但是没有啥优势:

// 假设这个 upload 里的回调函数就是 Promise 化的上传函数
const upload = queueGen(function asyncTimeOut(delay = 1e3){
    return new Promise(function(resolve, reject){
        setTimeout(resolve, delay)
        // 成功的时候执行 resolve
        // 失败的时候执行 reject
    });
});

// 假设这是全部分片
const sliceArray = [];
let currentSlice = sliceArray.shift();

// 上传单个分片
const singleUpload = slice => {
    upload(
        () => {
            // 上传成功,传下一个分片,直到没有分片
            currentSlice = sliceArray.shift();
            if(currentSlice){
                singleUpload(currentSlice)
            } else {
                // 这里说明全部分片都传完了,可以执行成功的逻辑
            }
        },
        slice,
        () => {
            // 上传失败,重试
            singleUpload(currentSlice)
        }
    )
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文