В Javascript метод ReadFile возвращает пустой массив, но когда данные журнала консоли отображаются в консоли

#javascript #ecmascript-6 #file-upload

#javascript #ecmascript-6 #загрузка файла

Вопрос:

Я хочу добавить все изображения в массив. Но когда я следующий код возвращает пустой массив. Однако, когда я регистрирую консоль, данные, относящиеся к изображениям, отображаются как на этом скриншоте. Кто-нибудь может дать мне решение

Это мой код 👇

 const readImages = uploader => {
      let images = []

      const selectedfiles = uploader.files

      for (let index = 0; index < selectedfiles.length; index  ) {
        const fileReader = new FileReader()

        fileReader.onload = fileLoadedEvent => {
          images.push(fileLoadedEvent.target.result)
        }

        fileReader.readAsDataURL(selectedfiles[index])
      }

      return images;
    }//End of readImages

    this._qs('#uploadImages').addEventListener('input', () => {
      const images = readImages(this._qs("#uploadImages"))
      console.log(images)
      for (let index = 0; index < images.length; index  ) {
        this._qs('#previewImages').innerHTML  = `<img src="${images[index]}" alt="image-${index}"/>`
      }
    })
  

Ответ №1:

Они images передаются в ваш массив onload , что означает, что это происходит асинхронно. Вы не можете работать с изображениями, пока они не будут возвращены в браузер. Лучший способ справиться с этим — readImages вернуть a Promise.all() и загрузить каждое отдельное изображение как собственное обещание, которое вы отправляете в Promise.all() массив.

 const readImage = (file) =>
  new Promise((resolve, reject) => {
    const fileReader = new FileReader();

    fileReader.onload = ({ target: { result } }) => resolve(result);
    fileReader.onerror = () => reject(fileReader.error);

    fileReader.readAsDataURL(file);
  });

const readImages = ({ files }) => {
  if (!files) {
    return Promise.reject('No files provided');
  }
  const imgPromises = [];
  files.forEach((file) => imgPromises.push(readImage(file)));

  return Promise.all(imgPromises);
};

// The input 'event' target will contain the value of the field
const onInput = ({ target: { value } }) => {
  readImages(value).then((imgArray) => {
    const preview = document.getElementById('previewImages');
    imgArray.forEach((img, index) => {
      preview.innerHTML  = `<img src="${img}" alt="image_${index}" />`;
    });
  });
};

document.getElementById('uploadImages').addEventListener('input', onInput);

  

Примечание: это действительно сырой код, чтобы дать вам представление об основах, и он не проверяет ваш конечный набор результатов на наличие ошибок. Он также использует деструктурирование объектов, которое не будет работать в старых браузерах.