从Javascript, spliced FileReader for large files with Promises, how?演变,它向我展示了Promise如何也可以解析一个函数,现在我仍然坚持使用相同但在Array.reduce函数内部 .
目标是我想在一个数组中上传一个文件(已经存在),其中每个数组项(文件)按顺序上传(即通过promises控制) .
然后,我明白答案是以某种方式在http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=es,但我无法理解如何将其应用到这里 . 我的数组不是promises数组,是一个文件数组 . 好吧,整件事情仍然让我感到困惑 .
这是我的代码,如果我能看到 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 uploaded_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 =''; uploaded_file = current;
upload()
.then(function(content){
// do stuff with "content"
console.log('here')
return Promise.resolve();
});
}); },Promise.resolve()) . then(function(){console.log('ein');});
function upload(){if(start <end){return new Promise(function(resolve){var chunk = uploaded_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 {uploaded_file = null; return 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();
}
}
1 回答
你非常接近!你需要 use 之前的值;它应该是一个承诺 . 将reduce的初始值设置为
Promise.resolve()
. 然后在reduce函数里面,而不是Promise.resolve().then(...)
. 你应该有类似的东西:你这里很重要
return
. 下次调用reduce函数时,这将变为previous
.upload
函数有很多问题 . biggest 问题是你传递变量的方式使得它很难阅读:)(并且容易出错!)如果您只是阅读文本文件,请改用
readAsText
. 注意我已将其重命名为readFile
,因为这是一个更准确的名称 .然后你的减少只是:
你有一个
upload_file
变量的大错误 . 该变量是reduce函数范围的本地变量,因此它将在upload
内undefined
. 将其作为参数传递:关于
var
的旁注 . 这就是为什么即使你在reduce函数中设置upload_file
和var
,它也就是为upload
调用该函数之前的任何东西: