【发布时间】:2016-12-13 19:32:42
【问题描述】:
从 Javascript, spliced FileReader for large files with Promises, how? 演变而来,它向我展示了 Promise 如何也可以解析函数,现在我被困在相同但在 Array.reduce 函数中。
目标是我想在数组中上传一个文件(已经上传),其中每个数组项(一个文件)按顺序上传(即通过承诺控制)。
然后,我知道答案不知何故在 http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=es 中,但我不明白如何将其应用于此处。我的数组不是一个承诺数组,是一个文件数组。好吧,整个事情对我来说仍然是模糊的。
这是我的代码,如果我能看到einconsole.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);
}
}
-
经过几次cmet后更新,现在好像可以了……还不确定
var uploading_file, start, temp_end, end, content; var BYTES_PER_CHUNK = 100000;
myArray.reduce(function(previous, current) { 返回上一个 .then(函数(){ BYTES_PER_CHUNK = 100000; 开始 = 0; temp_end = 开始 + BYTES_PER_CHUNK; end = parseInt(current.size); 如果(临时结束>结束)临时结束=结束; 内容=''; uploading_file = 当前;
upload() .then(function(content){ // do stuff with "content" console.log('here') return Promise.resolve(); });}); },Promise.resolve()) .then(函数(){ console.log('ein'); });
函数上传(){ 如果(开始结束)临时结束=结束; 解决(上传()); } } }); } 别的 { 上传文件=空; 返回 Promise.resolve(内容); } }
-
改进的代码,似乎可以工作,也许更容易阅读?
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(); } }
【问题讨论】:
-
如果您甚至从不参考
previous参数,那么使用 Array reduce 的意义何在 - 您基本上是在使用带有额外开销的forEach... -
你杀了我@TJCrowder - 现在我需要知道在基于数组将异步任务链接在一起时当前的最佳实践是什么......不需要详细信息,只需一个提示即可: p
-
@T.J.Crowder,没有冒犯,但你能扩大一点吗?除了 Array.reduce 之外,其余的代码错了吗?当必须将这些文件拼接成块时,我找不到另一种方法来进行顺序文件上传。你会怎么做?
-
@JaromandaX,你说得对,我的印象是我必须使用 Array.reduce 进行顺序上传,也许我必须使用它,但我在这里做错了
-
@Gerard:有几件事跳出来:1.
Promise.resolve().then(function() { return upload(); })基本上只是upload(),因为uploadreturns 一个承诺。 2.Promise.resolve();不使用时返回值是空操作。
标签: javascript promise filereader chain array-reduce