Javascript,用Promises上传Array.reduce中的几个文件,怎么样?
从Javascript演变而来,用Promise拼接FileReader来处理大文件,怎么做呢?它向我展示了Promise如何解析一个函数,现在我坚持使用相同的功能,但是在Array.reduce函数中。
目标是我想上传一个文件(已经这样做)在一个数组中,其中每个数组项(文件)被顺序上传(即通过promise进行控制)。
然后,我明白答案在http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=es中有所说明,但我无法理解如何将其应用到此处。 我的数组不是承诺数组,而是一组文件。 那么,整个事情仍然困扰着我。
这是我的代码,如果我可以看到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 uploading_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 =''; uploading_file = current;
upload()
.then(function(content){
// do stuff with "content"
console.log('here')
return Promise.resolve();
});
}); },Promise.resolve()).then(function(){console.log('ein');});
函数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; 返回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();
}
}
你非常接近! 您需要使用先前的值; 它应该是一个承诺。 将reduce的初始值设置为Promise.resolve()
。 然后在reduce函数中,而不是Promise.resolve().then(...)
。 你应该有这样的东西:
return previous
.then(function() { return upload(current); })
.then(function() { /* do stuff */ });
你return
这里很重要。 这将在下一次调用reduce函数时变为previous
。
upload
功能有很多问题。 最大的问题是你传递变量的方式使得它很难阅读:)(并且容易出错!)
如果您只是阅读文本文件,请改用readAsText
。 注意我将它重命名为readFile
,因为这是一个更准确的名称。
// returns a promise with the file contents
function readFile(file) {
return new Promise(function (resolve) {
var reader = new FileReader();
reader.onload = function(e) {
resolve(e.target.result);
};
reader.readAsText(file);
};
}
那么你的减少是简单的:
files.reduce(function(previous, file) {
return previous
.then(function() { return readFile(file); })
.then(function(contents) {
// do stuff
});
}, Promise.resolve());
虽然有一个很大的bug,但upload_file
变量。 该变量局限于reduce函数的范围,因此它将在upload
内部但undefined
。 相反,将其作为参数传递:
function upload(upload_file) { ... }
关于var
附注 这就是为什么即使您在reduce函数中使用var
设置了upload_file
,它也会是该函数被调用upload
之前的任何内容:
var a = 3;
function foo() {
var a = 4;
console.log(a); // 4
}
foo();
console.log(a); // 3
链接地址: http://www.djcxy.com/p/94623.html
上一篇: Javascript, uploading several files within an Array.reduce with Promises, how?
下一篇: Adding Metada and Options to S3 Objects when uploading a directory