Evolving from Javascript, spliced FileReader for large files with Promises, how?, which showed me how a Promise can also resolve a function, now I am stuck with the same but inside an Array.reduce function.
The goal is that I want to upload a file (which already does) within an array, where each array item (a file) is uploaded sequentially (i.e. controlled through promises).
Then, I understand that the answer is somehow in http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=es , but I cannot understand how to apply that to here. My array is not an array of promises, is an array of files. Well, the whole thing is still obfuscated to me.
This is my code, which would work if I could see the ein
console.log message:
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);
}
}
updated after several comments, it seems that now it works ... not sure yet
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'); });
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); } }
improved code, seems to work, perhaps easier to read?
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(); } }