NaturalWidth и naturalHeight возвращают 0

У меня есть код, который проверяет соотношение изображений. Это работает в 9 из 10 раз или даже чаще, но время от времени это не работает, потому что img.naturalWidth и img.naturalHeight возвращают 0. Я понимаю, что изображение не загружается в тот момент, когда я пытаюсь получить высота и ширина изображения, но я не знаю, почему это происходит редко. Код также находится внутри файла read.onload — решения, которое я нашел в большинстве онлайн-статей.

isValidFileRatio(selectedFile: Blob, width: number, height: number): any {
return new Promise((resolve, reject) => {
  const reader = new FileReader();

  const img = new Image();
  img.src = window.URL.createObjectURL(selectedFile);

  reader.readAsDataURL(selectedFile);
  reader.onload = () => {
    const ratio = img.naturalWidth / img.naturalHeight;
    
    resolve(ratio >= 1 && ratio <= 2);
  };
  reader.onerror = (error) => reject(error);
});

}

Любое решение или предложение приветствуется. Спасибо

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я думаю, что new FileReader() бесполезен и именно он стал причиной этой ошибки. Измените свой код следующим образом:

isValidFileRatio(selectedFile: Blob, width: number, height: number): any {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = window.URL.createObjectURL(selectedFile);
        
        img.onload = () => {
            const ratio = img.naturalWidth / img.naturalHeight;

            resolve(ratio >= 1 && ratio <= 2);
        };
        img.onerror = (error) => reject(error);
    });

Проблема в том, что вы используете filereader.onload вместо image.onload.

Вот как бы я это решил:

Я бы использовал createImageBitmap вместо FileReader, Image или Canvas, которые потребовали бы сочетания обратных вызовов и обещаний.

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

/**
 * @param {{ width: number, height: number }} image
 */
function isValidFileRatio (image) {
  const ratio = image.width / image.height
  return ratio >= 1 && ratio <= 2
}

// Just to get a simple dummy image/png blob for demo
var blob = new OffscreenCanvas(300, 200).getContext('2d').canvas.convertToBlob()

blob
  .then(createImageBitmap)
  .then(isValidFileRatio)
  .then(console.info)

Другие вопросы по теме