Javascript,用Promises拼接FileReader处理大文件,怎么样?

标签 javascript promise filereader chain

我正在尝试使用 FileReader 使用 Promise 来顺序读取多个文件。问题是我需要将读取操作分成几个 block 以使它们可行。通过这样做,我失去了 Promise 链。这就是以下代码中发生的情况,我在其中获取控制台日志 here ,然后catched (意味着我失去了链条),然后 inside然后finished 。不知何故,上传中的 promise 没有得到尊重。

这是代码(请转到最后一次编辑,但我保留原始文本)

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();
    }
  }
}

编辑1:我正在尝试的新代码,仍然是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:由于缺少 function(),所以出现了 catch 日志。以下代码似乎有效,但我看不到值 content我最后很感兴趣。

问题是,console.log 说,promise 在这里确实不起作用

here 1
here 2
here 4
here 3

代码:

        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);
            }
        }

最佳答案

您的 upload() 函数并不总是返回 Promise。它在 else 条件下起作用,但在 if 条件下则不然。您有一个 return 语句,但它位于回调内部,因此 upload 的调用者不会收到它。

尝试将其更改为:

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);
  }
}

现在,upload 始终返回 Promise,而不是 undefined

关于Javascript,用Promises拼接FileReader处理大文件,怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38815140/

相关文章:

javascript - 为什么两个相同的对象彼此不相等?

javascript - 仅在另一个脚本完成后才运行一个脚本的方法有哪些?

javascript - Cordova - 读取大图像会损坏图像

javascript - 根据条件添加类(使用 v-for 最后渲染的元素)

javascript - jQuery:如何获取表行中所选选项的值

javascript - HTML 表过滤器生成器不起作用

javascript - 如何串联 Promise

javascript - 在回调中使用 $q - 这可能吗?

android - 打开第三方 Epub 阅读器

java - 如何将数据读入 char 数组?