简体   繁体   English

Javascript,带有Promises的拼接FileReader用于大文件,如何?

[英]Javascript, spliced FileReader for large files with Promises, how?

I'm trying to use FileReader to read several files sequentially using promises for that. 我正在尝试使用FileReader来使用诺言顺序读取多个文件。 The problem is that I need to divide the reading operations in several chunks to make them doable. 问题是我需要将读取操作分成几部分以使其可行。 By doing so, I lose the Promise chain. 这样,我就失去了Promise链。 This is what happen in the following code, where I get the console log here , then catched (meaning I've lost the chain), then inside and then finished . 这就是下面的代码中发生的事情,在这里我在here获得了控制台日志,然后被catched (意味着我已经失去了链),然后inside然后finished Somehow the Promise in upload is not respected. 不知何故上传中的承诺。

Here it is the code (please go to the last EDIT, I keep the original text nonetheless) 这是代码(请转到最后的编辑,尽管如此,我仍保留原始文本)

var reader = new FileReader();
reader.onloadend = function(e) {
  if (e.target.readyState == 2) {
    console.log('inside')
    start = temp_end;
    temp_end = start + BYTES_PER_CHUNK;
    if (temp_end > end) temp_end = end;
    upload();
  }
};

Array.reduce(function(promise, item) {
  start = 0;
  temp_end = start + BYTES_PER_CHUNK;
  end = parseInt(totalsize);
  if (temp_end > end) temp_end = end;
  uploading_file = item;
  return upload()
  .then(function(){
    console.log('not shown');
  })
  .catch(console.log('catched'));
},0);

function upload() {
  return new Promise(function(resolve,reject) {
    if (start < end) {
      console.log('here')
      var chunk = uploading_file.slice(start, temp_end);
      reader.readAsBinaryString(chunk);
    } else {
      console.log('finished')
      uploading_file = null;
      resolve();
    }
  }
}

EDIT1: new code I'm trying, still the console.log stop 1 appears before the upload and the here 2 EDIT1:我正在尝试新代码,但console.log stop 1仍出现在upload之前, here 2

        var start = 0;
        var temp_end = start + BYTES_PER_CHUNK;
        var end = parseInt(item.size);
        if (temp_end > end) temp_end = end;
        uploading_file = item;
        console.log('here 1')
        Promise.resolve().then(function() {
            return upload();
        })
        .then(function(){
            console.log('here 2')
        })
        .catch(console.log('stop 1'));

        function upload() {
            console.log('upload')
            if (start < end) {
                var chunk = uploading_file.slice(start, temp_end);
                var reader = new FileReader();
                reader.readAsArrayBuffer(chunk);
                reader.onload = function(e) {
                    if (e.target.readyState == 2) {
                        start = temp_end;
                        temp_end = start + BYTES_PER_CHUNK;
                        if (temp_end > end) temp_end = end;
                        return upload();
                    }
                }
            } else {
                console.log('finished')
                uploading_file = null;
                return Promise.resolve();
            }
         }

EDIT2: The catch logs were there due to a lack of function(). EDIT2:由于缺少function(),捕获日志在那里。 The following code seems to work, but I cannot see the value content that I am interested at the end. 以下代码似乎有效,但是最后看不到我感兴趣的值content

The problem is that promises are indeed not working here, the console.log says 问题是,console.log说,诺言确实在这里不起作用。

here 1
here 2
here 4
here 3

The code: 编码:

        var item; // item is a file
        var BYTES_PER_CHUNK = 100000;
        var start = 0;
        var temp_end = start + BYTES_PER_CHUNK;
        var end = parseInt(item.size);
        if (temp_end > end) temp_end = end;
        var content = ''; // to be filled by the content of the file
        var uploading_file = item;
console.log('here 1');
        Promise.resolve().then(function() {
console.log('here 2');
            return upload();
        })
        .then(function(content){
console.log('here 4');
            console.log(content); // this is empty (!!)
        })
        .catch(function(){
            console.log('stop 1')
        });

        function upload() {
            if (start < end) {
                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;
                        return upload();
                    }
                }
            } else {
                uploading_file = null;
                console.log(content); // it shows the content of the file
console.log('here 3');
                return Promise.resolve(content);
            }
        }

Your upload() function does not always return a Promise. 您的upload()函数并不总是返回Promise。 It does in the else condition, but the if condition doesn't. 它在else条件中可以,但是if条件则不可以。 You have a return statement, but it's inside of a callback , so it won't be received by the caller of upload . 您有一个return语句,但是它在回调内部,因此upload的调用者不会接收它。

Try changing that to this: 尝试将其更改为此:

function upload() {
  if (start < end) {
    return new Promise(function (resolve, reject) {
      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;
    console.log(content); // it shows the content of the file
    return Promise.resolve(content);
  }
}

Now, upload always returns a Promise instead of undefined . 现在, upload始终返回Promise而不是undefined

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM