Axios:上传多个文件上传的进度

时间:2017-07-03 21:15:45

标签: javascript file-upload axios

关注https://github.com/mzabriskie/axios/blob/master/examples/upload/index.html我已设置了带进度条的文件上传。

但是,我有<input type="file" multiple>,因此上传内容如下:

for (var i=0; i<files.length; i++)
{
    var config = {
        onUploadProgress: function(progressEvent) {
            var what = Math.round( (progressEvent.loaded * 100) / progressEvent.total );
        }
    };
    axios.post(url, data, config)
        .then(function (response) {
    });                            
}

问题是:如何将上传进度(请参阅var what)分配给对应的文件?

我尝试过的所有事情都没有成功:

  • 回调函数onUploadProgress显然不会采取任何第二个参数:https://github.com/mzabriskie/axios#request-config

  • 注入的progressEvent对象不包含有关上传文件的任何信息。例如:

    progress { target: XMLHttpRequestUpload, isTrusted: true, lengthComputable: true, loaded: 181914, total: 181914, currentTarget: XMLHttpRequestUpload, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, composed: false }
    
  • 原则上可以访问循环变量i - 但是,它始终位于 last 位置(因为循环在onUploadProgress时已完成在上传期间被调用

  • 我无法找到一种方法来访问axios&#39;来自data

  • 内的onUploadProgress
  • this指的是:

    XMLHttpRequestUpload { onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, ontimeout: null, onloadend: null }
    

还有其他想法吗?

2 个答案:

答案 0 :(得分:4)

您可以使用一些Id作为参数创建一个返回另一个修饰函数的函数。

示例:

const myUploadProgress = (myFileId) => (progress) => {
  let percentage = Math.floor((progress.loaded * 100) / progress.total)
  console.log(myFileId)
  console.log(percentage)
}

for (var i=0; i<files.length; i++) {
  var config = {
    onUploadProgress: myUploadProgress(files[i].id)
  };

  axios.post(url, data, config).then(function (response) {});                            
}

如果你没有ES6,你可以这样做:

function myUploadProgress(myFileId) {
  return function(progress) {
    ...
  }
}

(我在我的项目中使用类似的代码,它就像魅力一样)

答案 1 :(得分:0)

这是一个变量范围问题。在JavaScript var中声明 function 范围内的变量。有很多潜在的解决方案,具体取决于目标浏览器支持的ES版本。我将使用相同的功能来演示:

setTimeout(function(){ console.log(i); }, i * 100);

使用var这将打印出来&#39; 5&#39; 5次。我们希望它打印出0 1 2 3 4

如果你有Array#forEach,你可以使用它,因为闭包创建了一个新的函数范围

[0, 1, 2, 3, 4].forEach(function(i) { 
    setTimeout(function(){ console.log(i); }, i * 100);
});

如果您有权访问letletconst会使用阻止作用域(即该变量的范围限定为最近的{{}} 1}})。

{ ... }

如果您无法访问其中任何一个,则可以使用IIFE。它真的很丑,但它完成了工作。

for (let i = 0; i < 5; i++) {
    setTimeout(function(){ console.log(i); }), i * 100);
}