#javascript #html #asynchronous
#javascript #HTML #асинхронный
Вопрос:
У меня есть этот код для рендеринга выбранного файла для загрузки:
//1
<input type="file" multiple id="my_html_uploader" />
//2
var files = myHtmlUploaderElem.files;
if (files.length > 0) {
for (var i = 0, file1; file1 = files[i]; i ) {
var reader = new FileReader();
reader.onload = (function(file2, i2) {
return function(e) {
alert("done!");
};
})(file1, i);
reader.readAsDataURL(f);
}
}
Как я могу уловить момент, когда обратный вызов reader.onload (…) был завершен для
а) отдельный файл
б) все файлы, которые были выбраны
?
Комментарии:
1. Для части B создайте глобальную переменную с длиной вашего массива. Каждый раз, когда выполняется ваш обратный вызов onload, вычтите единицу из счетчика и проверьте, равно ли оно нулю. если это так, выполните свой последний обратный вызов. Это то, что обещают. Все выполняется.
Ответ №1:
Создайте обещания, которые затем можно использовать Promise.all
для ожидания их всех:
const promises = []; // keep as much constant as possible
for (const file of files) { // way more beautiful, no need for an IIFE with "const" or "let"
let reader = new FileReader();
promises.push(new Promise((resolve, reject) => { // short for: function(resolve, reject) {
reader.onload = event => resolve(event.target.result);
reader.onerror = reject;
}));
reader.readAsDataURL(file);
}
Promise.all(promises).then(results => {
alert("all loaded");
// results is an array of file contents
}).catch(error => {
// one of the files failed to load, handle that here
});
Комментарии:
1. будет ли это работать во всех браузерах, включая старые?
2. Нет, этого не произойдет. Перенесите его обратно в ES5, чтобы получить лучшую поддержку.
3. Как это сделать в ES5?