【发布时间】:2016-08-07 14:29:16
【问题描述】:
我正在尝试使用 FileReader 使用 Promise 顺序读取多个文件。问题是我需要将读取操作分成几块以使其可行。这样一来,我就失去了 Promise 链。这就是在以下代码中发生的情况,我得到控制台日志here,然后是catched(意味着我丢失了链),然后是inside,然后是finished。不知何故,上传中的承诺没有得到尊重。
这是代码(请转到最后的编辑,我保留原文)
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:我正在尝试的新代码,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:由于缺少函数(),捕获日志在那里。下面的代码似乎可以工作,但最后我看不到我感兴趣的值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);
}
}
【问题讨论】:
-
我发现很难理解你想要做什么。您有很多未声明的变量、共享状态和不正确的代码(
Array.reduce?Array实际上是您真实代码中的变量吗?)。而upload似乎与上传无关,并且返回的承诺有时不会解决或拒绝。我将尝试猜测尝试,但如果您能准确说明代码的目的是什么。 -
请到最后的EDIT获取最终代码。无论如何,Array.reduce 意味着我有一个数组并且我使用了 reduce,但这部分代码对于我想要隔离的问题确实并不重要。我希望最后的代码更清楚我想要实现的目标?最终目标是按块读取文件,并通过 Promise 保持对它的控制
-
现在清楚多了,谢谢。
-
@GWorking 行得通,看来这家伙需要像你的stackoverflow.com/questions/57206375/multifile-upload-as-chunks 一样的解决方案@
-
@Jayavel 我已经删除了这个问题的链接,自从... 2 年前我就一直没有处理文件上传,这里有点生疏:)
标签: javascript promise filereader chain