我正在尝试使用 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/