【问题标题】:Axios: Upload progress for multiple file uploadsAxios:多个文件上传的上传进度
【发布时间】:2017-12-07 05:12:12
【问题描述】:

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 原则上是可访问的 - 但是,它始终位于最后 位置(因为在上传期间调用onUploadProgress 时循环已完成)

  • 我找不到从onUploadProgress 内部访问axios 的data 的方法

  • this指的是:

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

还有其他想法吗?

【问题讨论】:

  • 我在这里遗漏了什么吗?您在 for 循环中,一次上传一个文件。这意味着在每个 progressEvent 中,您已经在引用相应的文件。你能在 progressEvent 中添加一个监听器并打印出它的“总”值吗?我想你已经在查看相应的文件了。作为旁注,将配置从 for 循环中取出,您不需要为每个文件重新定义它。
  • 是的,谢谢,我已经认为答案可能是没有答案 ;-) 我只能在几天内尝试这个 - 我会报告......
  • 我也想知道如何实现这一点。使用 jQuery,我一直在使用“xhrFields”参数,但我不确定 Axios 是否有类似的东西。

标签: javascript file-upload axios


【解决方案1】:

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

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

使用 var 这将打印出 '5' 5 次。我们希望它打印出0 1 2 3 4

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

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

如果您有权访问 letletconst,则改为使用 block 范围(即,变量的范围为最近的 { ... } 集)。

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

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

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

【讨论】:

    【解决方案2】:

    您可以创建一个函数,该函数返回另一个带有一些 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) {
        ...
      }
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 2015-10-21
      • 2012-07-17
      • 2015-10-19
      • 2018-06-30
      • 2014-02-25
      • 1970-01-01
      相关资源
      最近更新 更多