Javascript,用Promises上传Array.reduce中的几个文件,怎么样?

从Javascript演变而来,用Promise拼接FileReader来处理大文件,怎么做呢?它向我展示了Promise如何解析一个函数,现在我坚持使用相同的功能,但是在Array.reduce函数中。

目标是我想上传一个文件(已经这样做)在一个数组中,其中每个数组项(文件)被顺序上传(即通过promise进行控制)。

然后,我明白答案在http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=es中有所说明,但我无法理解如何将其应用到此处。 我的数组不是承诺数组,而是一组文件。 那么,整个事情仍然困扰着我。

这是我的代码,如果我可以看到ein console.log消息,它将工作:

return myArray.reduce(function(previous, current) {
    var BYTES_PER_CHUNK = 100000;
    var start = 0;
    var temp_end = start + BYTES_PER_CHUNK;
    var end = parseInt(current.size);
    if (temp_end > end) temp_end = end;
    var content = ''; // to be filled by the content of the file
    var uploading_file = current;
    Promise.resolve().then(function() {
        return upload();
    })
    .then(function(content){
        // do stuff with the content
        Promise.resolve();
    });
},0)  // I add the 0 in case myArray has only 1 item
//},Promise.resolve()) goes here?

.then(function(){
    console.log('ein') // this I never see
});

function upload() {
  if (start < end) {
    return new Promise(function(resolve){
      var chunk = uploading_file.slice(start, temp_end);
      var reader = new FileReader();
      reader.readAsArrayBuffer(chunk);
      reader.onload = function(e) {
        if (e.target.readyState == 2) {
          content += new TextDecoder("utf-8").decode(e.target.result);
          start = temp_end;
          temp_end = start + BYTES_PER_CHUNK;
          if (temp_end > end) temp_end = end;
          resolve(upload());
        }
      }
    });
  } else {
    uploading_file = null;
    return Promise.resolve(content);
  }
}
  • 经过多次评论后更新,似乎现在它的工作......还不确定

    var uploading_file,start,temp_end,end,content; var BYTES_PER_CHUNK = 100000;

    myArray.reduce(function(previous,current){return previous.then(function(){BYTES_PER_CHUNK = 100000; start = 0; temp_end = start + BYTES_PER_CHUNK; end = parseInt(current.size); if(temp_end> end)temp_end = end; content =''; uploading_file = current;

    upload()
    .then(function(content){
        // do stuff with "content"
        console.log('here')
        return Promise.resolve();
    });
    

    }); },Promise.resolve()).then(function(){console.log('ein');});

    函数upload(){if(start <end){return new Promise(function(resolve){var chunk = uploading_file.slice(start,temp_end); var reader = new FileReader(); reader.readAsArrayBuffer(chunk); reader。 onload = function(e){if(e.target.readyState == 2){content + = new TextDecoder(“utf-8”)。decode(e.target.result); start = temp_end; temp_end = start + BYTES_PER_CHUNK ; if(temp_end> end)temp_end = end; resolve(upload());}}}); } else {uploading_file = null; 返回Promise.resolve(content); }}

  • 改进的代码,似乎工作,也许更容易阅读?

        var start, temp_end, end;
        var BYTES_PER_CHUNK = 100000;
    
        myArray.reduce(function(previous, current) {
            return previous
            .then(function() {
                start = 0;
                temp_end = start + BYTES_PER_CHUNK;
                end = parseInt(current.size);
                if (temp_end > end) temp_end = end;
                current.data = '';
    
                return upload(current)
                .then(function(){
                    // do other stuff
                    return Promise.resolve();
                });
            });
        },Promise.resolve())
        .then(function(){
          // do other stuff
        });
    
        function upload(current) {
            if (start < end) {
                return new Promise(function(resolve){
                    var chunk = current.slice(start, temp_end);
                    var reader = new FileReader();
                    reader.readAsText(chunk);
                    reader.onload = function(e) {
                        if (e.target.readyState == 2) {
                            current.data += e.target.result;
                            start = temp_end;
                            temp_end = start + BYTES_PER_CHUNK;
                            if (temp_end > end) temp_end = end;
                            resolve(upload(current));
                        }
                    }
                });
            } else {
                return Promise.resolve();
            }
        }
    

  • 你非常接近! 您需要使用先前的值; 它应该是一个承诺。 将reduce的初始值设置为Promise.resolve() 。 然后在reduce函数中,而不是Promise.resolve().then(...) 。 你应该有这样的东西:

    return previous
      .then(function() { return upload(current); })
      .then(function() { /* do stuff */ });
    

    return这里很重要。 这将在下一次调用reduce函数时变为previous


    upload功能有很多问题。 最大的问题是你传递变量的方式使得它很难阅读:)(并且容易出错!)

    如果您只是阅读文本文件,请改用readAsText 。 注意我将它重命名为readFile ,因为这是一个更准确的名称。

    // returns a promise with the file contents
    function readFile(file) {
        return new Promise(function (resolve) {
            var reader = new FileReader();
            reader.onload = function(e) {
                resolve(e.target.result);
            };
            reader.readAsText(file);
        };
    }
    

    那么你的减少是简单的:

    files.reduce(function(previous, file) {
        return previous
          .then(function() { return readFile(file); })
          .then(function(contents) {
              // do stuff
          });
    }, Promise.resolve());
    

    虽然有一个很大的bug,但upload_file变量。 该变量局限于reduce函数的范围,因此它将在upload内部但undefined 。 相反,将其作为参数传递:

    function upload(upload_file) { ... }
    

    关于var附注 这就是为什么即使您在reduce函数中使用var设置了upload_file ,它也会是该函数被调用upload之前的任何内容:

    var a = 3;
    
    function foo() {
      var a = 4;
      console.log(a); // 4
    }
    
    foo();
    console.log(a); // 3
    链接地址: http://www.djcxy.com/p/94623.html

    上一篇: Javascript, uploading several files within an Array.reduce with Promises, how?

    下一篇: Adding Metada and Options to S3 Objects when uploading a directory